<?php

namespace Wechat;

use app\common\model\Agent;
use app\common\model\System;
use app\common\model\WxOpen;
use think\Cookie;

class Wxobjopentest
{   //open平台常用
    const API_COMPONENT_TOKEN = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
    const API_CREATE_PREAUTHCODE = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=";
    const API_AURHORIZER_TOKEN = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=";
    const API_AUTHORIZATION_INFO = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=";
    const API_AUTHER_INFO = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=";
    const PAY_DELIVERNOTIFY = 'https://api.weixin.qq.com/pay/delivernotify?';
    const PAY_ORDERQUERY = 'https://api.weixin.qq.com/pay/orderquery?';
    const PAY_ORDERQUERYA = 'https://api.mch.weixin.qq.com/pay/orderquery';
    const PAY_REFUND_QUERY = 'https://api.mch.weixin.qq.com/pay/refundquery';
    const PAY_API_URL = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
    const MICROPAY_API_URL = "https://api.mch.weixin.qq.com/pay/micropay";
    const ACTIVECARDMKT = "https://api.weixin.qq.com/card/mkt/activity/create?access_token=";
    //微信电子发票
    const SET_CONTACT = "https://api.weixin.qq.com/card/invoice/setbizattr?action=set_contact&access_token=";//设置商户联系方式
    const GET_CONTACT = "https://api.weixin.qq.com/card/invoice/setbizattr?action=get_contact&access_token=";//获取商户联系方式
    const GET_AUTHURL = "https://api.weixin.qq.com/card/invoice/getauthurl?access_token=";//获取授权页链接
    const SET_PAY_MCH = "https://api.weixin.qq.com/card/invoice/setbizattr?action=set_pay_mch&access_token=";//关联商户号和商户平台
    const GET_PAY_MCH = "https://api.weixin.qq.com/card/invoice/setbizattr?action=get_pay_mch&access_token=";//关联商户号和商户平台
    const GET_AUTH_DATA = "https://api.weixin.qq.com/card/invoice/getauthdata?access_token=";//查询授权完成状态
    const MAKE_OUT_INVOICE = "https://api.weixin.qq.com/card/invoice/makeoutinvoice?access_token=";//开具蓝票
    //沙箱环境
    const SANDBOX_MICROPAY_API_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/micropay";
    const SANDBOX_PAY_ORDERQUERYA = 'https://api.mch.weixin.qq.com/sandboxnew/pay/orderquery';


    const OAUTH_PREFIX_OPEN = "https://open.weixin.qq.com/connect/oauth2";
    const OAUTH_AUTHORIZE_URL_OPEN = "/authorize?";
    const OAUTH_TOKEN_PREFIX_OPEN = "https://api.weixin.qq.com/sns/oauth2/";
    const OAUTH_TOKEN_URL_OPEN = "component/access_token?";
    const API_URL_PREFIX = 'https://api.weixin.qq.com/cgi-bin';
    const API_URL_OPEN = 'https://api.weixin.qq.com';
    const USER_INFO_URL = '/user/info?';
    const CARD_CODE_DECRYPE = '/card/code/decrypt?';        //解码接口
    const AUTH_URL_OPEN = "token?grant_type=client_credential&";
    const CMMB_PAY_URL = "http://scp.yufu99.com/scanpay-api/api/wxGZHUnifiedOrder20";
    const CMMB_SCANPAY_URL = "http://scp.yufu99.com/scanpay-api/api/unScanCodePay21";
    const CMMB_ORDER_QUERY = "http://scp.yufu99.com/scanpay-api/api/orderQuery20";
    const CMMB_TUIKUAN = "http://scp.yufu99.com/scanpay-api/api/refund20";
    const CMMB_REVERSE = "http://scp.yufu99.com/scanpay-api/api/revoke20";
    const CMMB_ORDER_CLOSE = "http://scp.yufu99.com/scanpay-api/api/close20";
    const GET_OPEN_ID_URL = "https://api.mch.weixin.qq.com/tools/authcodetoopenid";
    //小程序开放平台专用
    const XCX_MODIFY_DOMAIN = "https://api.weixin.qq.com/wxa/modify_domain?access_token=";//设置服务器域名
    const XCX_BIND_TESTER = "https://api.weixin.qq.com/wxa/bind_tester?access_token=";//绑定体验者
    const XCX_SETWEBVIEWDOMAIN = "https://api.weixin.qq.com/wxa/setwebviewdomain?access_token=";//成员管理
    const XCX_UNBIND_TESTER = "https://api.weixin.qq.com/wxa/unbind_tester?access_token=";//解绑体验者
    const XCX_COMMIT = "https://api.weixin.qq.com/wxa/commit?access_token=";//上传代码
    const XCX_GET_QRCODE = "https://api.weixin.qq.com/wxa/get_qrcode?access_token=";//获取体验二维码
    const XCX_GET_CATEGORY = "https://api.weixin.qq.com/wxa/get_category?access_token=";//获取小程序可选类目
    const XCX_GET_PAGE = "https://api.weixin.qq.com/wxa/get_page?access_token=";//获取小程序的第三方提交代码的页面配置
    const XCX_SUBMIT_AUDIT = "https://api.weixin.qq.com/wxa/submit_audit?access_token=";//发布小程序
    const XCX_SUBMIT_AUDIT_RELEASE = "https://api.weixin.qq.com/wxa/release?access_token=";//发布审核通过的小程序
    const XCX_GET_AUDITSTATUS = "https://api.weixin.qq.com/wxa/get_auditstatus?access_token=";//获取某个小程序审核状态
    const XCX_GET_LATEST = "https://api.weixin.qq.com/wxa/get_latest_auditstatus?access_token=";//查询最新一次提交的审核状态
    const XCX_RELEASE = "https://api.weixin.qq.com/wxa/release?access_token=";//发布已通过审核的小程序
    const XCX_REVERTCODERELAEASE = "https://api.weixin.qq.com/wxa/revertcoderelease?access_token=";//小程序版本回退
    const XCX_LOGIN = "https://api.weixin.qq.com/sns/component/jscode2session?";//获取openid
    const XCX_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&";//获取openid
    const XCX_MESSAGE_MB = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=";//发放模板消息
    const XCX_TPL_KU = "https://api.weixin.qq.com/cgi-bin/wxopen/template/library/get?access_token=";//获取模板消息详情
    const XCX_TPL_ADD = "https://api.weixin.qq.com/cgi-bin/wxopen/template/add?access_token=";//添加模板
    const XCX_GET_SYS_TEMPL = "https://api.weixin.qq.com/wxa/gettemplatedraftlist?access_token=";//获取草稿箱
    const XCX_GET_TPL_LIST = "https://api.weixin.qq.com/wxa/gettemplatelist?access_token=";//获取代码库
    const XCX_ADDTOTPL = "https://api.weixin.qq.com/wxa/addtotemplate?access_token=";//将草稿箱的草稿选为小程序代码模版
    const XCX_DEL_TPL = "https://api.weixin.qq.com/wxa/deletetemplate?access_token=";//删除小程序模板
    const XCX_GET_SEARCH_STATUS = "https://api.weixin.qq.com/wxa/getwxasearchstatus?access_token=";//查询小程序可搜索状态
    const XCX_SET_SEARCH_STATUS = "https://api.weixin.qq.com/wxa/changewxasearchstatus?access_token=";//设置小程序可以被搜索
    const XCX_UNCODE = "https://api.weixin.qq.com/wxa/undocodeaudit?access_token=";//设置小程序审核撤销

    //微信平台用
    const MSGTYPE_TEXT = 'text';
    const MSGTYPE_IMAGE = 'image';
    const MSGTYPE_LOCATION = 'location';
    const MSGTYPE_LINK = 'link';
    const MSGTYPE_EVENT = 'event';
    const MSGTYPE_MUSIC = 'music';
    const MSGTYPE_NEWS = 'news';
    const MSGTYPE_VOICE = 'voice';
    const MSGTYPE_VIDEO = 'video';
    const MSGTYPE_SHORTVIDEO = 'shortvideo';
    const EVENT_SUBSCRIBE = 'subscribe';       //订阅
    const EVENT_UNSUBSCRIBE = 'unsubscribe';   //取消订阅
    const EVENT_SCAN = 'SCAN';                 //扫描带参数二维码
    const EVENT_LOCATION = 'LOCATION';         //上报地理位置
    const EVENT_MENU_VIEW = 'VIEW';                     //菜单 - 点击菜单跳转链接
    const EVENT_MENU_CLICK = 'CLICK';                   //菜单 - 点击菜单拉取消息
    const EVENT_MENU_SCAN_PUSH = 'scancode_push';       //菜单 - 扫码推事件(客户端跳URL)
    const EVENT_MENU_SCAN_WAITMSG = 'scancode_waitmsg'; //菜单 - 扫码推事件(客户端不跳URL)
    const EVENT_MENU_PIC_SYS = 'pic_sysphoto';          //菜单 - 弹出系统拍照发图
    const EVENT_MENU_PIC_PHOTO = 'pic_photo_or_album';  //菜单 - 弹出拍照或者相册发图
    const EVENT_MENU_PIC_WEIXIN = 'pic_weixin';         //菜单 - 弹出微信相册发图器
    const EVENT_MENU_LOCATION = 'location_select';      //菜单 - 弹出地理位置选择器
    const EVENT_SEND_MASS = 'MASSSENDJOBFINISH';        //发送结果 - 高级群发完成
    const EVENT_SEND_TEMPLATE = 'TEMPLATESENDJOBFINISH';//发送结果 - 模板消息发送结果
    const EVENT_KF_SEESION_CREATE = 'kfcreatesession';  //多客服 - 接入会话
    const EVENT_KF_SEESION_CLOSE = 'kfclosesession';    //多客服 - 关闭会话
    const EVENT_KF_SEESION_SWITCH = 'kfswitchsession';  //多客服 - 转接会话
    const EVENT_CARD_PASS = 'card_pass_check';          //卡券 - 审核通过
    const EVENT_CARD_NOTPASS = 'card_not_pass_check';   //卡券 - 审核未通过
    const EVENT_CARD_USER_GET = 'user_get_card';        //卡券 - 用户领取卡券
    const EVENT_CARD_USER_DEL = 'user_del_card';        //卡券 - 用户删除卡券
    const EVENT_MERCHANT_ORDER = 'merchant_order';        //微信小店 - 订单付款通知
    const AUTH_URL = '/token?grant_type=client_credential&';
    const MENU_CREATE_URL = '/menu/create?';
    const MENU_GET_URL = '/menu/get?';
    const MENU_DELETE_URL = '/menu/delete?';
    const MENU_ADDCONDITIONAL_URL = '/menu/addconditional?';
    const MENU_DELCONDITIONAL_URL = '/menu/delconditional?';
    const MENU_TRYMATCH_URL = '/menu/trymatch?';
    const GET_TICKET_URL = '/ticket/getticket?';
    const CALLBACKSERVER_GET_URL = '/getcallbackip?';
    const QRCODE_CREATE_URL = '/qrcode/create?';
    const QR_SCENE = 0;
    const QR_LIMIT_SCENE = 1;
    const QRCODE_IMG_URL = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=';
    const SHORT_URL = '/shorturl?';
    const USER_GET_URL = '/user/get?';
    const USERS_INFO_URL = '/user/info/batchget?';
    const USER_UPDATEREMARK_URL = '/user/info/updateremark?';
    const GROUP_GET_URL = '/groups/get?';
    const USER_GROUP_URL = '/groups/getid?';
    const GROUP_CREATE_URL = '/groups/create?';
    const GROUP_UPDATE_URL = '/groups/update?';
    const GROUP_MEMBER_UPDATE_URL = '/groups/members/update?';
    const GROUP_MEMBER_BATCHUPDATE_URL = '/groups/members/batchupdate?';
    const CUSTOM_SEND_URL = '/message/custom/send?';
    const MEDIA_UPLOADNEWS_URL = '/media/uploadnews?';
    const MASS_SEND_URL = '/message/mass/send?';
    const TEMPLATE_GET_INDUSTRY = '/template/get_industry?';                    //获取行业
    const TEMPLATE_SET_INDUSTRY_URL = '/template/api_set_industry?';                    //设置行业
    const TEMPLATE_GET_ALL_PRIVATE_TEMPLATE = '/template/get_all_private_template?';
    const TEMPLATE_ADD_TPL_URL = '/template/api_add_template?';
    const TEMPLATE_SEND_URL = '/message/template/send?';
    const MASS_SEND_GROUP_URL = '/message/mass/sendall?';
    const MASS_DELETE_URL = '/message/mass/delete?';
    const MASS_PREVIEW_URL = '/message/mass/preview?';
    const MASS_QUERY_URL = '/message/mass/get?';
    const UPLOAD_MEDIA_URL = 'http://file.api.weixin.qq.com/cgi-bin';
    const MEDIA_UPLOAD_URL = '/media/upload?';
    const MEDIA_UPLOADIMG_URL = '/media/uploadimg?';//图片上传接口
    const MEDIA_GET_URL = '/media/get?';
    const MEDIA_VIDEO_UPLOAD = '/media/uploadvideo?';
    const MEDIA_FOREVER_UPLOAD_URL = '/material/add_material?';
    const MEDIA_FOREVER_NEWS_UPLOAD_URL = '/material/add_news?';
    const MEDIA_FOREVER_NEWS_UPDATE_URL = '/material/update_news?';
    const MEDIA_FOREVER_GET_URL = '/material/get_material?';
    const MEDIA_FOREVER_DEL_URL = '/material/del_material?';
    const MEDIA_FOREVER_COUNT_URL = '/material/get_materialcount?';
    const MEDIA_FOREVER_BATCHGET_URL = '/material/batchget_material?';
    const OAUTH_PREFIX = 'https://open.weixin.qq.com/connect/oauth2';
    const OAUTH_AUTHORIZE_URL = '/authorize?';
    const CGIBIN_MEDIA_UPLOADNEWS = '/cgi-bin/media/uploadnews?';       //上传图文消息素材
    const CGIBIN_MESSAGE_MASS_SEND = '/cgi-bin/message/mass/send?';     //根据OPENID群发消息
    const CGIBIN_MESSAGE_MASS_SENDALL = '/cgi-bin/message/mass/sendall?';       //根据标签进行群发
    ///多客服相关地址
    const CUSTOM_SERVICE_GET_RECORD = '/customservice/getrecord?';
    const CUSTOM_SERVICE_GET_KFLIST = '/customservice/getkflist?';
    const CUSTOM_SERVICE_GET_ONLINEKFLIST = '/customservice/getonlinekflist?';
    const API_BASE_URL_PREFIX = 'https://api.weixin.qq.com'; //以下API接口URL需要使用此前缀
    const OAUTH_TOKEN_URL = '/sns/oauth2/access_token?';
    const OAUTH_REFRESH_URL = '/sns/oauth2/refresh_token?';
    const OAUTH_USERINFO_URL = '/sns/userinfo?';
    const OAUTH_AUTH_URL = '/sns/auth?';
    ///多客服相关地址
    const CUSTOM_SESSION_CREATE = '/customservice/kfsession/create?';
    const CUSTOM_SESSION_CLOSE = '/customservice/kfsession/close?';
    const CUSTOM_SESSION_SWITCH = '/customservice/kfsession/switch?';
    const CUSTOM_SESSION_GET = '/customservice/kfsession/getsession?';
    const CUSTOM_SESSION_GET_LIST = '/customservice/kfsession/getsessionlist?';
    const CUSTOM_SESSION_GET_WAIT = '/customservice/kfsession/getwaitcase?';
    const CS_KF_ACCOUNT_ADD_URL = '/customservice/kfaccount/add?';
    const CS_KF_ACCOUNT_UPDATE_URL = '/customservice/kfaccount/update?';
    const CS_KF_ACCOUNT_DEL_URL = '/customservice/kfaccount/del?';
    const CS_KF_ACCOUNT_UPLOAD_HEADIMG_URL = '/customservice/kfaccount/uploadheadimg?';
    ///卡券相关地址
    const CARD_CREATE = '/card/create?';        //创建
    const CARD_DELETE = '/card/delete?';        //删除
    const CARD_UPDATE = '/card/update?';        //更新
    const CARD_GET = '/card/get?';
    const CARD_USER_GETCARDLIST = '/card/user/getcardlist?';
    const CARD_BATCHGET = '/card/batchget?';
    const CARD_MODIFY_STOCK = '/card/modifystock?';
    const CARD_LOCATION_BATCHADD = '/card/location/batchadd?';
    const CARD_LOCATION_BATCHGET = '/card/location/batchget?';
    const CARD_GETCOLORS = '/card/getcolors?';
    const CARD_QRCODE_CREATE = '/card/qrcode/create?';
    const CARD_CODE_CONSUME = '/card/code/consume?';                                        //
    const CARD_CODE_DECRYPT = '/card/code/decrypt?';
    const CARD_CODE_GET = '/card/code/get?';
    const CARD_CODE_UPDATE = '/card/code/update?';
    const CARD_CODE_UNAVAILABLE = '/card/code/unavailable?';
    const CARD_TESTWHILELIST_SET = '/card/testwhitelist/set?';
    const CARD_MEETINGCARD_UPDATEUSER = '/card/meetingticket/updateuser?';    //更新会议门票
    const CARD_MEMBERCARD_ACTIVATE = '/card/membercard/activate?';      //激活会员卡
    const CARD_MEMBERCARD_UPDATEUSER = '/card/membercard/updateuser?';    //更新会员卡
    const CARD_MOVIETICKET_UPDATEUSER = '/card/movieticket/updateuser?';   //更新电影票(未加方法)
    const CARD_BOARDINGPASS_CHECKIN = '/card/boardingpass/checkin?';     //飞机票-在线选座(未加方法)
    const CARD_LUCKYMONEY_UPDATE = '/card/luckymoney/updateuserbalance?';     //更新红包金额
    const SEMANTIC_API_URL = '/semantic/semproxy/search?'; //语义理解
    const CARD_MEMBERCARD_ACTIVATEUSERFORM_SET = '/card/membercard/activateuserform/set?';  //设置激活字段接口
    const CARD_MEMBERCARD_USERINFO_GET = '/card/membercard/userinfo/get?';  //查询用户信息
    const CARD_MEMBERCARD_ACTIVATETEMPINFO_GET = '/card/membercard/activatetempinfo/get?';   //获取跳转激活会员信息
    const DATACUBE_GETCARDMEMBERCARDDETAIL = '/datacube/getcardmembercarddetail?'; //查询单CARDID会员卡数据
    const DATACUBE_GETCARDMEMBERCARDINFO = '/datacube/getcardmembercardinfo?';      //查询会员卡列表
    const CARD_MPNEWS_GETHTML = '/card/mpnews/gethtml?';      //图文消息群发卡券获取
    const CARD_PAYGIFTCARD_ADD = '/card/paygiftcard/add?';      //支付即会员
    const CARD_PAYGIFTCARD_DELETE = '/card/paygiftcard/delete?';    //删除支付即会员
    const CARD_PAYGIFTCARD_GETBYID = '/card/paygiftcard/getbyid?';    //查询支付即会员
    const CARD_PAYGIFTCARD_BATCHGET = '/card/paygiftcard/batchget?';    //批量查询支付即会员
    const CARD_MEMBERCARD_ACTIVATE_GETURL = '/card/membercard/activate/geturl?'; //获取开卡组件链接
    const CARD_GIFTCARD_PAGE_ADD = '/card/giftcard/page/add?';          //创建货架
    const CARD_GIFTCARD_PAGE_UPDATE = '/card/giftcard/page/update?';     //修改货架
    const CARD_GIFTCARD_MAINTAIN_SET = '/card/giftcard/maintain/set?';   //上/下架 货架
    const CARD_GIFTCARD_PAY_WHITELIST_ADD = '/card/giftcard/pay/whitelist/add?';                    //开通礼品卡支付
    const CARD_GIFTCARD_PAY_SUBMCH_BIND = '/card/giftcard/pay/submch/bind?';            //傻瓜呼号绑定礼品卡小程序
    const CARD_GIFTCARD_WXA_SET = '/card/giftcard/wxa/set?';             //上传商户号到小程序
    const CARD_GIFTCARD_PAGE_GET = '/card/giftcard/page/get?';
    ///门店接口
    const CGI_BIN_POI_ADDPOI = '/cgi-bin/poi/addpoi?';   //门店创建
    const CGI_BIN_POI_UPDATEPOI = '/cgi-bin/poi/updatepoi?';  //修改门店服务信息
    const CGI_BIN_POI_DELPOI = '/cgi-bin/poi/delpoi?';   //门店删除
    const CGI_BIN_POI_GETWXCATEGORY = '/cgi-bin/poi/getwxcategory?';   //门店类目查询
    const CGI_BIN_POI_GETPOILIST = '/cgi-bin/poi/getpoilist?';   //门店列表查询
    const CGI_BIN_POI_GETPOI = '/cgi-bin/poi/getpoi?';   //门店信息查询
    const WXA_GET_STORE_LIST ='wxa/get_store_list?';    //门店小程序列表查询
    const WXA_GET_STORE_INFO = 'wxa/get_store_info?';    //门店小程序信息查询
    //腾讯地图
    const APIS_MAP_WS_GEOCODER = 'http://apis.map.qq.com/ws/geocoder/v1/?';
    ///数据分析接口
    static $DATACUBE_URL_ARR = array(        //用户分析
        'user' => array(
            'summary' => '/datacube/getusersummary?',        //获取用户增减数据（getusersummary）
            'cumulate' => '/datacube/getusercumulate?',        //获取累计用户数据（getusercumulate）
        ),
        'article' => array(            //图文分析
            'summary' => '/datacube/getarticlesummary?',        //获取图文群发每日数据（getarticlesummary）
            'total' => '/datacube/getarticletotal?',        //获取图文群发总数据（getarticletotal）
            'read' => '/datacube/getuserread?',            //获取图文统计数据（getuserread）
            'readhour' => '/datacube/getuserreadhour?',        //获取图文统计分时数据（getuserreadhour）
            'share' => '/datacube/getusershare?',            //获取图文分享转发数据（getusershare）
            'sharehour' => '/datacube/getusersharehour?',        //获取图文分享转发分时数据（getusersharehour）
        ),
        'upstreammsg' => array(        //消息分析
            'summary' => '/datacube/getupstreammsg?',        //获取消息发送概况数据（getupstreammsg）
            'hour' => '/datacube/getupstreammsghour?',    //获取消息分送分时数据（getupstreammsghour）
            'week' => '/datacube/getupstreammsgweek?',    //获取消息发送周数据（getupstreammsgweek）
            'month' => '/datacube/getupstreammsgmonth?',    //获取消息发送月数据（getupstreammsgmonth）
            'dist' => '/datacube/getupstreammsgdist?',    //获取消息发送分布数据（getupstreammsgdist）
            'distweek' => '/datacube/getupstreammsgdistweek?',    //获取消息发送分布周数据（getupstreammsgdistweek）
            'distmonth' => '/datacube/getupstreammsgdistmonth?',    //获取消息发送分布月数据（getupstreammsgdistmonth）
        ),
        'interface' => array(        //接口分析
            'summary' => '/datacube/getinterfacesummary?',    //获取接口分析数据（getinterfacesummary）
            'summaryhour' => '/datacube/getinterfacesummaryhour?',    //获取接口分析分时数据（getinterfacesummaryhour）
        )
    );
    ///微信摇一摇周边
    const SHAKEAROUND_DEVICE_APPLYID = '/shakearound/device/applyid?';//申请设备ID
    const SHAKEAROUND_DEVICE_UPDATE = '/shakearound/device/update?';//编辑设备信息
    const SHAKEAROUND_DEVICE_SEARCH = '/shakearound/device/search?';//查询设备列表
    const SHAKEAROUND_DEVICE_BINDLOCATION = '/shakearound/device/bindlocation?';//配置设备与门店ID的关系
    const SHAKEAROUND_DEVICE_BINDPAGE = '/shakearound/device/bindpage?';//配置设备与页面的绑定关系
    const SHAKEAROUND_MATERIAL_ADD = '/shakearound/material/add?';//上传摇一摇图片素材
    const SHAKEAROUND_PAGE_ADD = '/shakearound/page/add?';//增加页面
    const SHAKEAROUND_PAGE_UPDATE = '/shakearound/page/update?';//编辑页面
    const SHAKEAROUND_PAGE_SEARCH = '/shakearound/page/search?';//查询页面列表
    const SHAKEAROUND_PAGE_DELETE = '/shakearound/page/delete?';//删除页面
    const SHAKEAROUND_USER_GETSHAKEINFO = '/shakearound/user/getshakeinfo?';//获取摇周边的设备及用户信息
    const SHAKEAROUND_STATISTICS_DEVICE = '/shakearound/statistics/device?';//以设备为维度的数据统计接口
    const SHAKEAROUND_STATISTICS_PAGE = '/shakearound/statistics/page?';//以页面为维度的数据统计接口
    ///微信小店相关接口
    const MERCHANT_ORDER_GETBYID = '/merchant/order/getbyid?';//根据订单ID获取订单详情
    const MERCHANT_ORDER_GETBYFILTER = '/merchant/order/getbyfilter?';//根据订单状态/创建时间获取订单详情
    const MERCHANT_ORDER_SETDELIVERY = '/merchant/order/setdelivery?';//设置订单发货信息
    const MERCHANT_ORDER_CLOSE = '/merchant/order/close?';//关闭订单

    private $component_token;
    private $xcx_access_token;
    private $component_encodingAesKey;
    private $encrypt_type;
    private $component_appid;
    private $authorizer_appid;
    private $component_appsecret;
    private $component_access_token;
    private $open_access_token;
    private $jsapi_card_ticket;
    private $jsapi_ticket;
    private $postxml;
    private $open_ticket;
    private $authorizer_refresh_token;
    private $errCode;
    private $errMsg;
    private $_msg;
    private $_receive;
    private $debug = false;
    private $logcallback;
    private $partnerkey;
    private $cmmb_key;
    private $_text_filter;
    private $_funcflag;


    public function __construct($options)
    {
        $this->component_token = isset($options['component_token']) ? $options['component_token'] : '';
        $this->component_encodingAesKey = isset($options['component_encodingaeskey']) ? $options['component_encodingaeskey'] : '';
        $this->component_appid = isset($options['component_appid']) ? $options['component_appid'] : '';
        $this->component_appsecret = isset($options['component_appsecret']) ? $options['component_appsecret'] : '';
        $this->open_ticket = isset($options['open_ticket']) ? $options['open_ticket'] : '';
        $this->authorizer_appid = isset($options['authorizer_appid']) ? $options['authorizer_appid'] : '';
        $this->authorizer_refresh_token = isset($options['authorizer_refresh_token']) ? $options['authorizer_refresh_token'] : '';
        $this->partnerkey = isset($options['partnerkey']) ? $options['partnerkey'] : '';
        $this->cmmb_key = isset($options['cmmb_key']) ? $options['cmmb_key'] : '';

    }

    /*
     * 微信电子发票
     * Auther Mr.Lee
     * */
    public function setcontactinfo($data)
    {

        $result = $this->http_post(self::SET_CONTACT . $this->get_authorizer_access_token(), self::json_encode($data));


        if ($result) {
            $json = json_decode($result, true);
            return $json;
        }
        return false;
    }

    public function getcontactinfo()
    {
        $data = [];
        $result = $this->http_post(self::GET_CONTACT . $this->get_authorizer_access_token(), self::json_encode($data));


        if ($result) {
            $json = json_decode($result, true);
            return $json;
        }
        return false;
    }

    public function getauthurl($data)
    {
        $result = $this->http_post(self::GET_AUTHURL . $this->get_authorizer_access_token(), self::json_encode($data));


        if ($result) {
            $json = json_decode($result, true);
            return $json;
        }
        return false;
    }

    public function setpaymch($data)
    {

        $result = $this->http_post(self::SET_PAY_MCH . $this->get_authorizer_access_token(), self::json_encode($data));


        if ($result) {
            $json = json_decode($result, true);
            return $json;
        }
        return false;
    }

    public function getpaymch()
    {
        $data = [];
        $result = $this->http_post(self::GET_PAY_MCH . $this->get_authorizer_access_token(), self::json_encode($data));


        if ($result) {
            $json = json_decode($result, true);
            return $json;
        }
        return false;
    }

    public function getauthdata($data)
    {

        $result = $this->http_post(self::GET_AUTH_DATA . $this->get_authorizer_access_token(), self::json_encode($data));


        if ($result) {
            $json = json_decode($result, true);
            return $json;
        }
        return false;
    }

    public function makeoutinvoice($data)
    {

        $result = $this->http_post(self::MAKE_OUT_INVOICE . $this->get_authorizer_access_token(), self::json_encode($data));

        return $result;
        if ($result) {
            $json = json_decode($result, true);
            return $json;
        }
        return false;
    }

    /**
     * For weixin server validation
     */
    private function checkSignature($str = '')
    {
        $signature = isset($_GET["signature"]) ? $_GET["signature"] : '';
        $signature = isset($_GET["msg_signature"]) ? $_GET["msg_signature"] : $signature; //如果存在加密验证则用加密验证段
        $timestamp = isset($_GET["timestamp"]) ? $_GET["timestamp"] : '';
        $nonce = isset($_GET["nonce"]) ? $_GET["nonce"] : '';
        $token = $this->component_token;
        $tmpArr = array($token, $timestamp, $nonce, $str);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);
        if ($tmpStr == $signature) {
            return true;
        } else {
            return false;
        }
    }

    public function get_open_id($param)
    {
        $param['nonce_str'] = self::generateNonceStr();
        $param['sign'] = self::getPaySignature($param);

        $data = self::xml_encode($param);

        $result = $this->http_post(self::GET_OPEN_ID_URL, $data);

        $this->postxml = $result;
        $results = $this->xml_to_array();
        return $results;
    }

    public function sendTemplateMessage2($data)
    {
//        if ($this->checkopenAuth2()) return false;

        $result = $this->http_post(self::API_URL_PREFIX . self::TEMPLATE_SEND_URL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data));

        return $result;
    }

    public function checkopenAuth2($appid = '', $appsecret = '')
    {
        if (!$appid || !$appsecret) {
            $component_appid = $this->component_appid;
            $component_appsecret = $this->component_appsecret;
        }
        $System = new System();
        $Agent = new Agent();
        $at = $Agent->where(array('component_appid' => $component_appid))->find();

        if ($at && $at['at_addtime'] + $at['expires_in'] >= time()) {
            $this->component_access_token = $at['component_access_token'];


            return $at['component_access_token'];

        }
        $param['component_appid'] = $component_appid;
        $param['component_appsecret'] = $component_appsecret;
        $param['component_verify_ticket'] = $this->open_ticket;


        $result = $this->http_post(self::API_COMPONENT_TOKEN, json_encode($param));
        return $result;

        if ($result) {
            $json = json_decode($result, true);
            if (!$json || isset($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            $this->component_access_token = $json['component_access_token'];

            $expire = $json['expires_in'] ? intval($json['expires_in']) - 200 : 3600;

//            $aa = $System->save(array('component_access_token' => $json['component_access_token'], 'expires_in' => $expire, 'at_addtime' => time()), ['id' => 1]);

            $bb = $Agent->save(array('component_access_token' => $json['component_access_token'], 'expires_in' => $expire, 'at_addtime' => time()), ['component_appid' => $this->component_appid]);

            return $json['component_access_token'];
        }

        return false;
    }

    //获取 open access token
    public function checkopenAuth($appid = '', $appsecret = '')
    {
        if (!$appid || !$appsecret) {
            $component_appid = $this->component_appid;
            $component_appsecret = $this->component_appsecret;
        }
        $System = new System();
        $Agent = new Agent();
        $at = $Agent->where(array('component_appid' => $component_appid))->find();

        if ($at && $at['at_addtime'] + $at['expires_in'] >= time()) {
            $this->component_access_token = $at['component_access_token'];


            return $at['component_access_token'];

        }
        $param['component_appid'] = $component_appid;
        $param['component_appsecret'] = $component_appsecret;
        $param['component_verify_ticket'] = $this->open_ticket;
    

        $result = $this->http_post(self::API_COMPONENT_TOKEN, json_encode($param));
        return $result;
        if ($result) {
            $json = json_decode($result, true);
            if (!$json || isset($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            $this->component_access_token = $json['component_access_token'];

            $expire = $json['expires_in'] ? intval($json['expires_in']) - 200 : 3600;

//            $aa = $System->save(array('component_access_token' => $json['component_access_token'], 'expires_in' => $expire, 'at_addtime' => time()), ['id' => 1]);

            $bb = $Agent->save(array('component_access_token' => $json['component_access_token'], 'expires_in' => $expire, 'at_addtime' => time()), ['component_appid' => $this->component_appid]);

            return $json['component_access_token'];
        }

        return false;
    }

    public function reclog($param, $type)
    {
        try {
//            file_put_contents('/data2/html/osapi/exelog/wxobj/' . date("Y-m-d") . '.txt', $type . '-' . json_encode($param, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
        } catch (\Exception $e) {
            $data2 = array('code' => '9099', 'message' => $e->getMessage());
        }
    }

    public function get_pre_auth_code()
    {


        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
//        return $this->component_access_token;
        $param['component_appid'] = $this->component_appid;
        $result = $this->http_post(self::API_CREATE_PREAUTHCODE . $this->component_access_token, json_encode($param));
        $result = json_decode($result, true);
//        return $result;

//        Cookie::set('pre_auth_code', $result['pre_auth_code'], $result['expires_in'] - 700);
        $pre_auth_code = $result['pre_auth_code'];

        return $pre_auth_code;


    }

    //设置服务器域名
    public function set_xcx_domain($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_MODIFY_DOMAIN . $this->get_authorizer_access_token(), json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    //设置小程序可被搜索
    public function set_xcx_search($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_SET_SEARCH_STATUS . $this->get_authorizer_access_token(), json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    //获取小程序可被搜索
    public function get_xcx_search()
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_get(self::XCX_GET_SEARCH_STATUS . $this->get_authorizer_access_token());
        $result = json_decode($result, true);
        return $result;
    }

    //小程序撤销审核
    public function get_xcx_uncode()
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_get(self::XCX_UNCODE . $this->get_authorizer_access_token());
        $result = json_decode($result, true);
        return $result;
    }

    //设置服务器域名
    public function xcx_addtotpl($param)
    {

        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_ADDTOTPL . $this->component_access_token, json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    //删除小程序模板
    public function xcx_tpl_del($param)
    {

        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_DEL_TPL . $this->component_access_token, json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    //上传代码
    public function xcx_commit($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_COMMIT . $this->get_authorizer_access_token(), json_encode($param, JSON_UNESCAPED_UNICODE));
        $result = json_decode($result, true);
        return $result;
    }

    public function xcx_tpl_ku($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_TPL_KU . $this->get_authorizer_access_token(), json_encode($param, JSON_UNESCAPED_UNICODE));
        $result = json_decode($result, true);
        return $result;
    }

    public function xcx_tpl_add($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_TPL_ADD . $this->get_authorizer_access_token(), json_encode($param, JSON_UNESCAPED_UNICODE));
        $result = json_decode($result, true);
        return $result;
    }

    //小程序草稿箱
    public function xcx_sys_templ()
    {

        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_get(self::XCX_GET_SYS_TEMPL . $this->component_access_token);
        $result = json_decode($result, true);
        return $result;
    }

    //小程序模板库
    public function xcx_tpl_list()
    {

        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_get(self::XCX_GET_TPL_LIST . $this->component_access_token);
        $result = json_decode($result, true);
        return $result;
    }

    //获取体验二维码
    public function xcx_getqrcode()
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->getFile(self::XCX_GET_QRCODE . $this->get_authorizer_access_token(), "xcx_code/", $this->authorizer_appid . time() . ".jpg");
//        $result = json_decode($result, true);
        return $result;
    }

    private function getFile($url, $path = '', $filename = '', $type = 0)
    {
        if ($url == '') {
            return false;
        }
        //获取远程文件数据
        if ($type === 0) {
            $ch = curl_init();
            $timeout = 5;
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);//最长执行时间
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);//最长等待时间

            $img = curl_exec($ch);
            curl_close($ch);
        }
        if ($type === 1) {
            ob_start();
            readfile($url);
            $img = ob_get_contents();
            ob_end_clean();
        }
        if ($type === 2) {
            $img = file_get_contents($url);
        }
        //判断下载的数据 是否为空 下载超时问题
        if (empty($img)) {
            throw new \Exception("下载错误,无法获取下载文件！");
        }

        //没有指定路径则默认当前路径
        if ($path === '') {
            $path = "./";
        }
        //如果命名为空
        if ($filename === "") {
            $filename = md5($img);
        }
        //获取后缀名
        $ext = substr($url, strrpos($url, '.'));
        if ($ext && strlen($ext) < 5) {
            $filename .= $ext;
        }

        //防止"/"没有添加
        $path = rtrim($path, "/") . "/";
        //var_dump($path.$filename);die();
        $fp2 = @fopen($path . $filename, 'a');

        fwrite($fp2, $img);
        fclose($fp2);
        //echo "finish";
        return "/" . $path . $filename;
    }

    public function xcx_login($param)
    {

        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_get(self::XCX_LOGIN . "appid=" . $this->authorizer_appid . "&js_code=" . $param['code'] . "&grant_type=authorization_code&component_appid=" . $this->component_appid . "&component_access_token=" . $this->component_access_token);
        $result = json_decode($result, true);
        return $result;

    }

    //获取小程序可选类目
    public function xcx_getcategory()
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_get(self::XCX_GET_CATEGORY . $this->get_authorizer_access_token());
        $result = json_decode($result, true);
        return $result;
    }

    //获取小程序的第三方提交代码的页面配置
    public function xcx_getpage()
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_get(self::XCX_GET_PAGE . $this->get_authorizer_access_token());
        $result = json_decode($result, true);
        return $result;
    }

    //发布代码
    public function xcx_submitaudit($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_SUBMIT_AUDIT . $this->get_authorizer_access_token(), json_encode($param, JSON_UNESCAPED_UNICODE));
        $result = json_decode($result, true);
        return $result;
    }

    public function xcx_access_token($appid = "", $appsecret = "")
    {
        $Wxopen = new WxOpen();
        if (!$appid || !$appsecret) {

            $authorizer_appid = $this->authorizer_appid;

            $xcx_appsecret = $Wxopen->where(['authorizer_appid' => $authorizer_appid])->value('xcx_appsecret');
            $component_appsecret = $xcx_appsecret;
        }
        $System = new System();
        $at = $Wxopen->where(array('authorizer_appid' => $authorizer_appid))->find();

        if ($at && $at['xcx_at_addtime'] + $at['xcx_expires_in'] >= time()) {
            $this->xcx_access_token = $at['xcx_access_token'];


            return $at['xcx_access_token'];

        }

        $result = $this->http_get(self::XCX_ACCESS_TOKEN . "appid=" . $authorizer_appid . "&secret=" . $xcx_appsecret);


        if ($result) {
            $json = json_decode($result, true);
            if (!$json || isset($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            $this->xcx_access_token = $json['access_token'];

            $expire = $json['expires_in'] ? intval($json['expires_in']) - 200 : 3600;

            $aa = $Wxopen->save(array('xcx_access_token' => $this->xcx_access_token, 'xcx_expires_in' => $expire, 'xcx_at_addtime' => time()), ['authorizer_appid' => $authorizer_appid]);


            return $json['access_token'];
        }

        return false;
//        $result = $this->http_get(self::XCX_ACCESS_TOKEN ."appid=".$this->component_appid."&secret=".$this->component_appsecret);

        $result = json_decode($result, true);
        return $result;

    }

    //发布模板消息
    public function xcx_sendmessage($param)
    {

        $result = $this->http_post(self::XCX_MESSAGE_MB . $this->xcx_access_token(), json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    //获取小程序审核状态
    public function xcx_getauditstatus($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_GET_AUDITSTATUS . $this->get_authorizer_access_token(), json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    //查询小程序最新一次提交的审核状态
    public function xcx_getlatest()
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_get(self::XCX_GET_LATEST . $this->get_authorizer_access_token());
        $result = json_decode($result, true);
        return $result;
    }

    //绑定业务域名


    public function set_xcx_webviewdomain($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_SETWEBVIEWDOMAIN . $this->get_authorizer_access_token(), json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    public function set_xcx_fb($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_ . $this->get_authorizer_access_token(), json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    //绑定体验者
    public function xcx_bind_tester($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_BIND_TESTER . $this->get_authorizer_access_token(), json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    //解绑体验者
    public function xcx_unbind_tester($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_UNBIND_TESTER . $this->get_authorizer_access_token(), json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    //发布已通过审核的小程序
    public function xcx_release($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_SUBMIT_AUDIT_RELEASE . $this->get_authorizer_access_token(), json_encode($param, JSON_FORCE_OBJECT));
        $result = json_decode($result, true);
        return $result;
    }

    //小程序版本回退
    public function xcx_revertcode($param)
    {

//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::XCX_REVERTCODERELAEASE . $this->get_authorizer_access_token(), json_encode($param));
        $result = json_decode($result, true);
        return $result;
    }

    public function get_auther_info($param)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $param['component_appid'] = $this->component_appid;
        $result = $this->http_post(self::API_AUTHER_INFO . $this->component_access_token, json_encode($param));
        $result = json_decode($result, true);
        return $result;

    }


    /**
     * For weixin server validation
     * @param bool $return 是否返回
     */
    //消息解密
    public function message_decrypt($return = false)
    {
        libxml_disable_entity_loader(true);
        $msg = (array)simplexml_load_string($this->postxml, 'SimpleXMLElement', LIBXML_NOCDATA);
        return $msg;
    }

    public function valid($return = false)
    {
        $encryptStr = "";

        if ($_SERVER['REQUEST_METHOD'] == "POST") {
            libxml_disable_entity_loader(true);
            $postStr = file_get_contents("php://input");
            $array = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);

            $this->encrypt_type = isset($_GET["encrypt_type"]) ? $_GET["encrypt_type"] : '';

            if ($this->encrypt_type == 'aes') { //aes加密

                $encryptStr = $array['Encrypt'];
                $pc = new Prpcrypt($this->component_encodingAesKey);
                $array = $pc->decrypt($encryptStr, $this->component_appid);

                if (!isset($array[0]) || ($array[0] != 0)) {
                    if (!$return) {
                        die('decrypt error!');
                    } else {
                        return false;
                    }
                }

                $this->postxml = $array[1];

                if (!$this->component_appid)
                    $this->component_appid = $array[2];//为了没有appid的订阅号。
            } else {
                $this->postxml = $postStr;
            }

        }
        if (!$this->checkSignature($encryptStr)) {
            if ($return)
                return false;
            else
                die('no access');
        }
        return true;


    }

    public function xml_to_array()
    {
        libxml_disable_entity_loader(true);

        $array = (array)simplexml_load_string($this->postxml, 'SimpleXMLElement', LIBXML_NOCDATA);

        return $array;

    }

    public function authorization_info($data)
    {
        $param['component_appid'] = $this->component_appid;
        $param['authorization_code'] = $data;
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::API_AUTHORIZATION_INFO . $this->component_access_token, json_encode($param));

        $result2 = json_decode($result, true);
        return $result2;
    }

    //刷新授权令牌
    public function get_authorizer_access_token($authorizer_appid = '')
    {
        if (!$authorizer_appid) {
            $authorizer_appid = $this->authorizer_appid;
        }
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $WxOpen = new WxOpen();
        $at = $WxOpen->where(array('authorizer_appid' => $authorizer_appid))->find();

        if ($at && $at['at_addtime'] + $at['at_expires_in'] >= time()) {
            $authorizer_access_token = $at['at_access_token'];

            return $authorizer_access_token;

        } else {
            $params['component_appid'] = $this->component_appid;
            $params['authorizer_appid'] = $authorizer_appid;
            $params['authorizer_refresh_token'] = $this->authorizer_refresh_token;
            $result = $this->http_post(self::API_AURHORIZER_TOKEN . $this->component_access_token, json_encode($params));
            $result2 = json_decode($result, true);

            if (!isset($result2['errcode'])) {
                if ($at) {
                    $datas['at_access_token'] = $result2['authorizer_access_token'];
                    $datas['at_expires_in'] = 7000;
                    $datas['at_addtime'] = time();
                    $up = $WxOpen->save($datas, ['authorizer_appid' => $authorizer_appid]);
                }

                $authorizer_access_token = $result2['authorizer_access_token'];
            } else {
                $this->errCode = $result2['errcode'];
                $this->errMsg = $result2['errmsg'];
                return false;
            }

        }

        return $authorizer_access_token;

    }

    public function getopenOauthRedirect($callback, $state = '', $scope = 'snsapi_userinfo')
    {

        return self::OAUTH_PREFIX_OPEN . self::OAUTH_AUTHORIZE_URL_OPEN . 'appid=' . $this->authorizer_appid . '&redirect_uri=' . urlencode($callback) . '&response_type=code&scope=' . $scope . '&state=' . $state . '&component_appid=' . $this->component_appid . '#wechat_redirect';
    }

    public function getopenOauthCode($callback, $state = '', $scope = '')
    {
        $url = self::OAUTH_PREFIX_OPEN . self::OAUTH_AUTHORIZE_URL_OPEN . 'appid=' . $this->authorizer_appid . '&redirect_uri=' . urlencode($callback) . '&response_type=code&scope=' . $scope . '&state=' . $state . '&component_appid=' . $this->component_appid . '#wechat_redirect';
//        $result = $this->http_get($url);
        header('location:' . $url);
//        return $url;
    }

    public function getopenOauthCodet($callback, $state = '', $scope = '')
    {
        $url = self::OAUTH_PREFIX_OPEN . self::OAUTH_AUTHORIZE_URL_OPEN . 'appid=' . $this->authorizer_appid . '&redirect_uri=' . urlencode($callback) . '&response_type=code&scope=snsapi_userinfo' . '&state=' . $state . '&component_appid=' . $this->component_appid . '#wechat_redirect';
//        $result = $this->http_get($url);
        header('location:' . $url);
//        return $url;
    }

    /**
     * 通过code获取Access Token
     * @return array {access_token,expires_in,refresh_token,openid,scope}
     */
    public function getOpenoauthAccessToken()
    {
        $code = isset($_GET['code']) ? $_GET['code'] : '';
        if (!$code) return false;
        $url = self::OAUTH_TOKEN_PREFIX_OPEN . self::OAUTH_TOKEN_URL_OPEN . 'appid=' . $this->authorizer_appid . '&code=' . $code . '&grant_type=authorization_code&component_appid=' . $this->component_appid . "&component_access_token=" . $this->checkopenAuth();
        return $this->checkopenAuth();
        $result = $this->http_get($url);
       // $result['url'] = $url;
        return $url;
        if ($result) {
            $json = json_decode($result, true);
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            $this->user_token = $json['access_token'];
            return $json;
        }
        return false;
    }

    public function activemkt($data)
    {

        $result = $this->http_post(self::ACTIVECARDMKT . $this->get_authorizer_access_token(), self::json_encode($data));


        if ($result) {
            $json = json_decode($result, true);
            return $json;
        }
        return false;
    }

    //获取用户基本信息
    public function getUserInfo($openid)
    {

        $result = $this->http_get(self::API_URL_PREFIX . self::USER_INFO_URL . 'access_token=' . $this->get_authorizer_access_token() . '&openid=' . $openid . "&lang=zh_CN");
//        $json = json_decode($result, true);
//        return $json;

        if ($result) {
            $json = json_decode($result, true);

//     //       $data['wx_open_id'] = $wx_open_id;
//     //       $data['gh_id'] = $datas['gh_id'];
//            $data['statu'] = $json['subscribe'];
//            $data['openid'] = $json['openid'];
//            $data['nickname'] = $json['nickname'];
//            $data['sex'] = $json['sex'];
//            $data['city'] = $json['city'];
//            $data['head_url'] =$json['headimgurl'];
//            $data['groupid'] = $json['groupid'];
//            $data['create_time'] = time();

//            return $data;
            if (isset($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }

    //获取用户基本信息
    /*
     * 含unionid
     *
     * */
    public function getUserInfos($openid)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
//        $url = self::API_URL_OPEN . self::OAUTH_USERINFO_URL . 'access_token=' . $this->checkopenAuth() . '&openid=' . $openid ."&lang=zh_CN";
        $result = $this->http_get(self::API_URL_OPEN . self::OAUTH_USERINFO_URL . 'access_token=' . $this->checkopenAuth() . '&openid=' . $openid);
        $json = json_decode($result, true);
        return $json;
        if ($result) {
            $json = json_decode($result, true);
            if (isset($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }

    //获取用户OPENID
    public function getUserOpenid()
    {

    }

    /**
     * 设置发送消息
     * @param array $msg 消息数组
     * @param bool $append 是否在原消息数组追加
     */
    public function Message($msg = '', $append = false)
    {

        if (is_null($msg)) {
            $this->_msg = array();
        } elseif (is_array($msg)) {
            if ($append)
                $this->_msg = array_merge($this->_msg, $msg);
            else
                $this->_msg = $msg;
            return $this->_msg;
        } else {
            return $this->_msg;
        }
    }
    /**
     * 日志记录，可被重载。
     * @param mixed $log 输入日志
     * @return mixed
     */
    /**
     * 获取微信服务器发来的信息
     */
    public function getRev()
    {
        libxml_disable_entity_loader(true);
        if ($this->_receive) return $this;
        $postStr = !empty($this->postxml) ? $this->postxml : file_get_contents("php://input");
        //兼顾使用明文又不想调用valid()方法的情况

        $this->log($postStr);
        if (!empty($postStr)) {
            $this->_receive = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        }


        return $this;
    }

    protected function log($log)
    {
        if ($this->debug && function_exists($this->logcallback)) {
            if (is_array($log)) $log = print_r($log, true);
            return call_user_func($this->logcallback, $log);
        }
    }

    /**
     * 获取微信服务器发来的信息
     */
    public function getRevData()
    {
        return $this->_receive;
    }

    /**
     * 获取消息发送者
     */
    public function getRevFrom()
    {
        if (isset($this->_receive['FromUserName']))
            return $this->_receive['FromUserName'];
        else
            return false;
    }

    /**
     * 获取消息接受者
     */
    public function getRevTo()
    {
        if (isset($this->_receive['ToUserName']))
            return $this->_receive['ToUserName'];
        else
            return false;
    }

    /**
     * 获取接收消息的类型
     */
    public function getRevType()
    {
        if (isset($this->_receive['MsgType']))
            return $this->_receive['MsgType'];
        else
            return false;
    }

    /**
     * 获取消息ID
     */
    public function getRevID()
    {
        if (isset($this->_receive['MsgId']))
            return $this->_receive['MsgId'];
        else
            return false;
    }

    /**
     * 获取消息发送时间
     */
    public function getRevCtime()
    {
        if (isset($this->_receive['CreateTime']))
            return $this->_receive['CreateTime'];
        else
            return false;
    }

    /**
     * 获取接收消息内容正文
     */
    public function getRevContent()
    {
        if (isset($this->_receive['Content']))
            return $this->_receive['Content'];
        else if (isset($this->_receive['Recognition'])) //获取语音识别文字内容，需申请开通
            return $this->_receive['Recognition'];
        else
            return false;
    }

    /**
     * 获取接收消息图片
     */
    public function getRevPic()
    {
        if (isset($this->_receive['PicUrl']))
            return array(
                'mediaid' => $this->_receive['MediaId'],
                'picurl' => (string)$this->_receive['PicUrl'],    //防止picurl为空导致解析出错
            );
        else
            return false;
    }

    /**
     * 获取接收消息链接
     */
    public function getRevLink()
    {
        if (isset($this->_receive['Url'])) {
            return array(
                'url' => $this->_receive['Url'],
                'title' => $this->_receive['Title'],
                'description' => $this->_receive['Description']
            );
        } else
            return false;
    }

    /**
     * 获取接收地理位置
     */
    public function getRevGeo()
    {
        if (isset($this->_receive['Location_X'])) {
            return array(
                'x' => $this->_receive['Location_X'],
                'y' => $this->_receive['Location_Y'],
                'scale' => $this->_receive['Scale'],
                'label' => $this->_receive['Label']
            );
        } else
            return false;
    }

    /**
     * 获取上报地理位置事件
     */
    public function getRevEventGeo()
    {
        if (isset($this->_receive['Latitude'])) {
            return array(
                'x' => $this->_receive['Latitude'],
                'y' => $this->_receive['Longitude'],
                'precision' => $this->_receive['Precision'],
            );
        } else
            return false;
    }

    /**
     * 获取接收事件推送
     */
    public function getRevEvent()
    {
        if (isset($this->_receive['Event'])) {
            $array['event'] = $this->_receive['Event'];
        }
        if (isset($this->_receive['EventKey'])) {
            $array['key'] = $this->_receive['EventKey'];
        }
        if (isset($array) && count($array) > 0) {
            return $array;
        } else {
            return false;
        }
    }

    /*
     * 自定义卡券方法
     * 获取接收卡券ID
     */
    public function getRevCardid()
    {
        if (isset($this->_receive['CardId']))
            return $this->_receive['CardId'];
        else
            return false;
    }

    /*
     *获取接收卡券code
     */
    public function getRevCode()
    {
        if (isset($this->_receive['UserCardCode']))
            return $this->_receive['UserCardCode'];
        else
            return false;
    }

    /*
     * 获取接收核销来源
     */
    public function getRevConsumeSource()
    {
        if (isset($this->_receive['ConsumeSource']))
            return $this->_receive['ConsumeSource'];
        else
            return false;
    }

    /*
     *获取接收门店名称，当前卡券核销的门店名称
     */
    public function getRevLocationName()
    {
        if (isset($this->_receive['LocationName']))
            return $this->_receive['LocationName'];
        else
            return false;
    }

    /*
     * 获取核销改卡券核销员的openid
     */
    public function getRevStaffOpenId()
    {
        if (isset($this->_receive['StaffOpenId']))
            return $this->_receive['StaffOpenId'];
        else
            return false;
    }

    /*
     *
     */
    public function getRevVerifyCode()
    {
        if (isset($this->_receive['VerifyCode']))
            return $this->_receive['VerifyCode'];
        else
            return false;
    }

    /*
     *
     */
    public function getRevRemarkAmount()
    {
        if (isset($this->_receive['RemarkAmount']))
            return $this->_receive['RemarkAmount'];
        else
            return false;
    }

    /*
     *
     */
    public function getRevOuterStr()
    {
        if (isset($this->_receive['OuterStr']))
            return $this->_receive['OuterStr'];
        else
            return false;
    }


    /**
     * 获取自定义菜单的扫码推事件信息
     *
     * 事件类型为以下两种时则调用此方法有效
     * Event     事件类型，scancode_push
     * Event     事件类型，scancode_waitmsg
     *
     * @return: array | false
     * array (
     *     'ScanType'=>'qrcode',
     *     'ScanResult'=>'123123'
     * )
     */
    public function getRevScanInfo()
    {
        if (isset($this->_receive['ScanCodeInfo'])) {
            if (!is_array($this->_receive['ScanCodeInfo'])) {
                $array = (array)$this->_receive['ScanCodeInfo'];
                $this->_receive['ScanCodeInfo'] = $array;
            } else {
                $array = $this->_receive['ScanCodeInfo'];
            }
        }
        if (isset($array) && count($array) > 0) {
            return $array;
        } else {
            return false;
        }
    }

    /**
     * 获取自定义菜单的图片发送事件信息
     *
     * 事件类型为以下三种时则调用此方法有效
     * Event     事件类型，pic_sysphoto        弹出系统拍照发图的事件推送
     * Event     事件类型，pic_photo_or_album  弹出拍照或者相册发图的事件推送
     * Event     事件类型，pic_weixin          弹出微信相册发图器的事件推送
     *
     * @return: array | false
     * array (
     *   'Count' => '2',
     *   'PicList' =>array (
     *         'item' =>array (
     *             0 =>array ('PicMd5Sum' => 'aaae42617cf2a14342d96005af53624c'),
     *             1 =>array ('PicMd5Sum' => '149bd39e296860a2adc2f1bb81616ff8'),
     *         ),
     *   ),
     * )
     *
     */
    public function getRevSendPicsInfo()
    {
        if (isset($this->_receive['SendPicsInfo'])) {
            if (!is_array($this->_receive['SendPicsInfo'])) {
                $array = (array)$this->_receive['SendPicsInfo'];
                if (isset($array['PicList'])) {
                    $array['PicList'] = (array)$array['PicList'];
                    $item = $array['PicList']['item'];
                    $array['PicList']['item'] = array();
                    foreach ($item as $key => $value) {
                        $array['PicList']['item'][$key] = (array)$value;
                    }
                }
                $this->_receive['SendPicsInfo'] = $array;
            } else {
                $array = $this->_receive['SendPicsInfo'];
            }
        }
        if (isset($array) && count($array) > 0) {
            return $array;
        } else {
            return false;
        }
    }

    /**
     * 获取自定义菜单的地理位置选择器事件推送
     *
     * 事件类型为以下时则可以调用此方法有效
     * Event     事件类型，location_select        弹出地理位置选择器的事件推送
     *
     * @return: array | false
     * array (
     *   'Location_X' => '33.731655000061',
     *   'Location_Y' => '113.29955200008047',
     *   'Scale' => '16',
     *   'Label' => '某某市某某区某某路',
     *   'Poiname' => '',
     * )
     *
     */
    public function getRevSendGeoInfo()
    {
        if (isset($this->_receive['SendLocationInfo'])) {
            if (!is_array($this->_receive['SendLocationInfo'])) {
                $array = (array)$this->_receive['SendLocationInfo'];
                if (empty($array['Poiname'])) {
                    $array['Poiname'] = "";
                }
                if (empty($array['Label'])) {
                    $array['Label'] = "";
                }
                $this->_receive['SendLocationInfo'] = $array;
            } else {
                $array = $this->_receive['SendLocationInfo'];
            }
        }
        if (isset($array) && count($array) > 0) {
            return $array;
        } else {
            return false;
        }
    }

    /**
     * 获取接收语音推送
     */
    public function getRevVoice()
    {
        if (isset($this->_receive['MediaId'])) {
            return array(
                'mediaid' => $this->_receive['MediaId'],
                'format' => $this->_receive['Format'],
            );
        } else
            return false;
    }

    /**
     * 获取接收视频推送
     */
    public function getRevVideo()
    {
        if (isset($this->_receive['MediaId'])) {
            return array(
                'mediaid' => $this->_receive['MediaId'],
                'thumbmediaid' => $this->_receive['ThumbMediaId']
            );
        } else
            return false;
    }

    /**
     * 获取接收TICKET
     */
    public function getRevTicket()
    {
        if (isset($this->_receive['Ticket'])) {
            return $this->_receive['Ticket'];
        } else
            return false;
    }

    /**
     * 获取二维码的场景值
     */
    public function getRevSceneId()
    {
        if (isset($this->_receive['EventKey'])) {
            return str_replace('qrscene_', '', $this->_receive['EventKey']);
        } else {
            return false;
        }
    }

    /**
     * 获取主动推送的消息ID
     * 经过验证，这个和普通的消息MsgId不一样
     * 当Event为 MASSSENDJOBFINISH 或 TEMPLATESENDJOBFINISH
     */
    public function getRevTplMsgID()
    {
        if (isset($this->_receive['MsgID'])) {
            return $this->_receive['MsgID'];
        } else
            return false;
    }

    /**
     * 获取模板消息发送状态
     */
    public function getRevStatus()
    {
        if (isset($this->_receive['Status'])) {
            return $this->_receive['Status'];
        } else
            return false;
    }

    /**
     * 获取群发或模板消息发送结果
     * 当Event为 MASSSENDJOBFINISH 或 TEMPLATESENDJOBFINISH，即高级群发/模板消息
     */
    public function getRevResult()
    {
        if (isset($this->_receive['Status'])) //发送是否成功，具体的返回值请参考 高级群发/模板消息 的事件推送说明
            $array['Status'] = $this->_receive['Status'];
        if (isset($this->_receive['MsgID'])) //发送的消息id
            $array['MsgID'] = $this->_receive['MsgID'];
        //以下仅当群发消息时才会有的事件内容
        if (isset($this->_receive['TotalCount']))     //分组或openid列表内粉丝数量
            $array['TotalCount'] = $this->_receive['TotalCount'];
        if (isset($this->_receive['FilterCount']))    //过滤（过滤是指特定地区、性别的过滤、用户设置拒收的过滤，用户接收已超4条的过滤）后，准备发送的粉丝数
            $array['FilterCount'] = $this->_receive['FilterCount'];
        if (isset($this->_receive['SentCount']))     //发送成功的粉丝数
            $array['SentCount'] = $this->_receive['SentCount'];
        if (isset($this->_receive['ErrorCount']))    //发送失败的粉丝数
            $array['ErrorCount'] = $this->_receive['ErrorCount'];
        if (isset($array) && count($array) > 0) {
            return $array;
        } else {
            return false;
        }
    }
    /**
     * 转发多客服消息
     * Example: $obj->transfer_customer_service($customer_account)->reply();
     * @param string $customer_account 转发到指定客服帐号：test1@test
     */
    public function transfer_customer_service($customer_account = '')
    {
        $msg = array(
            'ToUserName' => $this->getRevFrom(),
            'FromUserName' => $this->getRevTo(),
            'CreateTime' => time(),
            'MsgType' => 'transfer_customer_service',
        );
        if (!$customer_account) {
            $msg['TransInfo'] = array('KfAccount' => $customer_account);
        }
        $this->Message($msg);
        return $this;
    }
    /**
     * 获取多客服会话状态推送事件 - 接入会话
     * 当Event为 kfcreatesession 即接入会话
     * @return string | boolean  返回分配到的客服
     */
    public function getRevKFCreate()
    {
        if (isset($this->_receive['KfAccount'])) {
            return $this->_receive['KfAccount'];
        } else
            return false;
    }

    /**
     * 获取多客服会话状态推送事件 - 关闭会话
     * 当Event为 kfclosesession 即关闭会话
     * @return string | boolean  返回分配到的客服
     */
    public function getRevKFClose()
    {
        if (isset($this->_receive['KfAccount'])) {
            return $this->_receive['KfAccount'];
        } else
            return false;
    }

    /**
     * 获取多客服会话状态推送事件 - 转接会话
     * 当Event为 kfswitchsession 即转接会话
     * @return array | boolean  返回分配到的客服
     * {
     *     'FromKfAccount' => '',      //原接入客服
     *     'ToKfAccount' => ''            //转接到客服
     * }
     */
    public function getRevKFSwitch()
    {
        if (isset($this->_receive['FromKfAccount']))     //原接入客服
            $array['FromKfAccount'] = $this->_receive['FromKfAccount'];
        if (isset($this->_receive['ToKfAccount']))    //转接到客服
            $array['ToKfAccount'] = $this->_receive['ToKfAccount'];
        if (isset($array) && count($array) > 0) {
            return $array;
        } else {
            return false;
        }
    }

    /**
     * 发送客服消息
     * @param array $data 消息结构{"touser":"OPENID","msgtype":"news","news":{...}}
     * @return boolean|array
     */
    public function sendCustomMessage($data)
    {

        $result = $this->http_post(self::API_URL_PREFIX . self::CUSTOM_SEND_URL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data));
        if ($result) {
            $json = json_decode($result, true);
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }

        return $result;
    }

    /**
     * 批量获取关注用户列表
     * @param unknown $next_openid
     */
    public function getUserList($next_openid = '')
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $result = $this->http_get(self::API_URL_PREFIX . self::USER_GET_URL . 'access_token=' . $this->get_authorizer_access_token() . '&next_openid=' . $next_openid);

        if ($result) {
            $json = json_decode($result, true);
            if (isset($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }

    /**
     * 批量获取关注者详细信息
     * @param array $openids user_list{{'openid:xxxxxx'},{},{}}
     * @return array user_info_list{subscribe,openid,nickname,sex,city,province,country,language,headimgurl,subscribe_time,[unionid]}{}{}...
     * 注意：unionid字段 只有在用户将公众号绑定到微信开放平台账号后，才会出现。建议调用前用isset()检测一下
     */
    public function getUsersInfo($openids)
    {
//        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $result = $this->http_post(self::API_URL_PREFIX . self::USERS_INFO_URL . 'access_token=' . $this->get_authorizer_access_token(), json_encode($openids));

        if ($result) {
            $json = json_decode($result, true);

            if (isset($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }


            return $json;
        }
        return false;
    }


    /**
     * 获取卡券事件推送 - 卡卷审核是否通过
     * 当Event为 card_pass_check(审核通过) 或 card_not_pass_check(未通过)
     * @return string|boolean  返回卡券ID
     */
    public function getRevCardPass()
    {
        if (isset($this->_receive['CardId']))
            return $this->_receive['CardId'];
        else
            return false;
    }

    /**
     * 获取卡券事件推送 - 领取卡券
     * 当Event为 user_get_card(用户领取卡券)
     * @return array|boolean
     */
    public function getRevCardGet()
    {
        if (isset($this->_receive['CardId']))     //卡券 ID
            $array['CardId'] = $this->_receive['CardId'];
        if (isset($this->_receive['IsGiveByFriend']))    //是否为转赠，1 代表是，0 代表否。
            $array['IsGiveByFriend'] = $this->_receive['IsGiveByFriend'];
        $array['OldUserCardCode'] = $this->_receive['OldUserCardCode'];
        if (isset($this->_receive['UserCardCode']) && !empty($this->_receive['UserCardCode'])) //code 序列号。自定义 code 及非自定义 code的卡券被领取后都支持事件推送。
            $array['UserCardCode'] = $this->_receive['UserCardCode'];
        if (isset($array) && count($array) > 0) {
            return $array;
        } else {
            return false;
        }
    }

    /**
     * 获取卡券事件推送 - 删除卡券
     * 当Event为 user_del_card(用户删除卡券)
     * @return array|boolean
     */
    public function getRevCardDel()
    {
        if (isset($this->_receive['CardId']))     //卡券 ID
            $array['CardId'] = $this->_receive['CardId'];
        if (isset($this->_receive['UserCardCode']) && !empty($this->_receive['UserCardCode'])) //code 序列号。自定义 code 及非自定义 code的卡券被领取后都支持事件推送。
            $array['UserCardCode'] = $this->_receive['UserCardCode'];
        if (isset($array) && count($array) > 0) {
            return $array;
        } else {
            return false;
        }
    }

    //支付授权码获取openid
    public function get_pay_openid($param)
    {
        $param['nonce_str'] = self::generateNonceStr();
        $param['sign'] = self::getPaySignature($param);

        $data = self::xml_encode($param);

        $result = $this->http_post(self::GET_OPEN_ID_URL, $data);
        $this->postxml = $result;
        $results = $this->xml_to_array();
        return $results;
    }


    /*
     * 自定义菜单
     * */
    public function createMenu($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $result = $this->http_post(self::API_URL_PREFIX . self::MENU_CREATE_URL . 'access_token=' . $this->get_authorizer_access_token(), $data);
        if ($result) {
            $json = json_decode($result, true);
//            $datas = self::json_encode($data);
            return $json;
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return true;
        }
        return false;
    }

    /**
     * 获取菜单(认证后的订阅号可用)
     * @return array('menu'=>array(....s))
     */
    public function getMenu()
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $result = $this->http_get(self::API_URL_PREFIX . self::MENU_GET_URL . 'access_token=' . $this->get_authorizer_access_token());
        if ($result) {
            $json = json_decode($result, true);
            if (!$json || isset($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }

    /**
     * 删除菜单(认证后的订阅号可用)
     * @return boolean
     */
    public function deleteMenu()
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $result = $this->http_get(self::API_URL_PREFIX . self::MENU_DELETE_URL . 'access_token=' . $this->get_authorizer_access_token());
        if ($result) {
            $json = json_decode($result, true);
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return true;
        }
        return false;
    }



    /*
     * 会员卡接口
     *
     *
     */
    //创建会员卡
    public function createUserCard($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = [];
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CREATE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        return json_decode($result, true);

    }

    //更新会员卡
    public function updateUserCard($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_UPDATE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //删除会员卡
    public function delUserCard($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_DELETE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //接口激活
    public function cardFire($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MEMBERCARD_ACTIVATE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        $result = json_decode($result, true);
        return $result;
        if ($result['errcode'] == 0) {
            return $result;
        } else {
            return false;
        }

    }

    //一键激活请求字段提交
    public function oneFire($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MEMBERCARD_ACTIVATEUSERFORM_SET . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //更新会员会员卡信息
    public function updateUserInfo($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MEMBERCARD_UPDATEUSER . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询用户信息-(积分查询)
    public function userGetInfo($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MEMBERCARD_USERINFO_GET . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }


    //设置过期会员卡
    public function delineUserCard($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CODE_UNAVAILABLE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);

    }

    //查询单类会员卡数据
    public function queryUserCard($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::DATACUBE_GETCARDMEMBERCARDDETAIL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }


    //查询单张卡券核销状态
    public function getCardState($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CODE_GET . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询某个cardid的卡券详情
    public function getCardInfo($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_GET . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询用户已领取会员卡
    public function userGetCard($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_USER_GETCARDLIST . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询会员卡概览(列表)       某个公众平台创建的某个时段的会员卡的相关数据
    public function queryCardList($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::DATACUBE_GETCARDMEMBERCARDDETAIL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询卡券列表  单次50条
    public function cardGetList($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_BATCHGET . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //CODE解密
    public function decryptCode($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CODE_DECRYPE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //开卡组件链接
    public function geturlActivate($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MEMBERCARD_ACTIVATE_GETURL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //获取跳转激活信息 CARD_MEMBERCARD_ACTIVATETEMPINFO_GET
    public function getuserActivate($data)
    {
//        if (!$this->component_access_token && !$this->get_authorizer_access_token()) return false;
//        return
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MEMBERCARD_ACTIVATETEMPINFO_GET . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
//        return self::API_BASE_URL_PREFIX . self::CARD_MEMBERCARD_ACTIVATETEMPINFO_GET . 'access_token=' . $this->get_authorizer_access_token();
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    /*
    * 卡券接口
    *
    *
    */

    public function uploadImg($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //原先的上传多媒体文件接口使用 self::UPLOAD_MEDIA_URL 前缀
        $result = $this->http_post(self::API_URL_PREFIX . self::MEDIA_UPLOADIMG_URL . 'access_token=' . $this->get_authorizer_access_token(), $data, true);
        $json = json_decode($result, true);
        return $json;
        if ($result) {
            $json = json_decode($result, true);
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }


    //卡券核销
    public function consumeCode($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CODE_CONSUME . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //修改卡券库存
    public function cardStock($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MODIFY_STOCK . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //卡券二维码投放
    public function cardQrcode($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_QRCODE_CREATE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    public function cardQrcodetest($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_QRCODE_CREATE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //卡券群发获取
    public function cardMpnews($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MPNEWS_GETHTML . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //上传图文消息素材
    public function uploadNews($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CGIBIN_MEDIA_UPLOADNEWS . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //根据OPENID群发投放
    public function mesgSend($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CGIBIN_MESSAGE_MASS_SEND . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //根据标签群发
    public function mesgSendAll($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CGIBIN_MESSAGE_MASS_SENDALL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //发送客服消息接口投放
    public function custMesg($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_URL_PREFIX . self::CUSTOM_SEND_URL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //支付即会员投放
    public function payPut($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_PAYGIFTCARD_ADD . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //删除支付即会员
    public function payPutDel($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_PAYGIFTCARD_DELETE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询支付即会员
    public function payPutGet($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_PAYGIFTCARD_GETBYID . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //批量查询支付即会员
    public function payPutGetList($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_PAYGIFTCARD_BATCHGET . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }
    /*
    * 门店接口
    *
    *
    */
    //创建门店
    public function creatStore($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CGI_BIN_POI_ADDPOI . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //修改门店服务信息
    public function editStore($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CGI_BIN_POI_UPDATEPOI . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //删除门店
    public function delStore($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CGI_BIN_POI_DELPOI . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询门店类目
    public function getStoreGory()
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_get(self::API_BASE_URL_PREFIX . self::CGI_BIN_POI_GETWXCATEGORY . 'access_token=' . $this->get_authorizer_access_token());
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询门店列表
    public function getStoreList($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CGI_BIN_POI_GETPOILIST . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }
    //查询门店列表
    public function getStoreListApp($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::WXA_GET_STORE_LIST . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询门店列表
    public function getStoreInfoApp($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::WXA_GET_STORE_INFO . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //查询门店信息
    public function getStoreInfo($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CGI_BIN_POI_GETPOI . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //礼品卡接口  创建货架
    public function createGiftPage($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_GIFTCARD_PAGE_ADD . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //礼品卡接口  修改货架
    public function updateGiftPage($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_GIFTCARD_PAGE_UPDATE . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //礼品卡接口  货架信息
    public function getGiftPage($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_GIFTCARD_PAGE_GET . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //礼品卡接口  上/下架 货架
    public function maintainGiftPageSet($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_GIFTCARD_MAINTAIN_SET . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    // CARD_GIFTCARD_PAY_WHITELIST_ADD
    //礼品卡接口  绑定商户号到小程序
    public function payGiftPageBind($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_GIFTCARD_PAY_SUBMCH_BIND . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data, JSON_UNESCAPED_UNICODE));
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //礼品卡接口  激活商户号支付
    public function applyGiftPayWhitelist($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_GIFTCARD_PAY_WHITELIST_ADD . 'access_token=' . $this->get_authorizer_access_token(), json_encode($data, JSON_UNESCAPED_UNICODE));
//        return self::API_BASE_URL_PREFIX . self::CARD_GIFTCARD_PAY_WHITELIST_ADD . 'access_token=' . $this->get_authorizer_access_token();
//        return $result;
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    //礼品卡接口  上传礼品卡小程序代码
    public function GiftPayWxaSet($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        //发送请求并转换json发送
        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_GIFTCARD_WXA_SET . 'access_token=' . $this->get_authorizer_access_token(), json_encode($data, JSON_UNESCAPED_UNICODE));
//        return self::API_BASE_URL_PREFIX . self::CARD_GIFTCARD_PAY_WHITELIST_ADD . 'access_token=' . $this->get_authorizer_access_token();
//        return $result;
        //根据返回值判断是否成功
        return json_decode($result, true);
    }

    /*
     * 腾讯地图接口
     *
     *
     */
    public function getWsLocation($data)
    {
        $url = self::APIS_MAP_WS_GEOCODER . 'location=' . $data['location'] . '&key=' . $data['key'] . '&get_poi=' . $data['get_poi'];
        $result = $this->http_get($url);
        return json_decode($result, true);
//        $url = self::APIS_MAP_WS_GEOCODER .  $data['location'] . '&key=' . $data['key'] . '&get_poi=' . $data['get_poi'];
//        return $url;

    }

    /*
     * 请求方法
     * */
    private function http_request($url, $data)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SAFE_UPLOAD, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// 我们在POST数据哦！
        $aPOST = array();
        foreach ($data as $key => $val) {
            $aPOST[] = $key . "=" . urlencode($val);
        }
        $strPOST = join("&", $aPOST);

        curl_setopt($ch, CURLOPT_POST, TRUE);
// 把post的变量加上
        curl_setopt($ch, CURLOPT_POSTFIELDS, $strPOST);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }

    /**
     * 获取订单ID - 订单付款通知
     * 当Event为 merchant_order(订单付款通知)
     * @return orderId|boolean
     */
    public function getRevOrderId()
    {
        if (isset($this->_receive['OrderId']))     //订单 ID
            return $this->_receive['OrderId'];
        else
            return false;
    }

    public static function xmlSafeStr($str)
    {
        return '<![CDATA[' . preg_replace("/[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]/", '', $str) . ']]>';
    }

    /**
     * 数据XML编码
     * @param mixed $data 数据
     * @return string
     */
    public static function data_to_xml($data)
    {
        $xml = '';
        foreach ($data as $key => $val) {
            is_numeric($key) && $key = "item id=\"$key\"";
            $xml .= "<$key>";
            $xml .= (is_array($val) || is_object($val)) ? self::data_to_xml($val) : self::xmlSafeStr($val);
            list($key,) = explode(' ', $key);
            $xml .= "</$key>";
        }
        return $xml;
    }

    /**
     * XML编码
     * @param mixed $data 数据
     * @param string $root 根节点名
     * @param string $item 数字索引的子节点名
     * @param string $attr 根节点属性
     * @param string $id 数字索引子节点key转换的属性名
     * @param string $encoding 数据编码
     * @return string
     */
    public function xml_encode($data, $root = 'xml', $item = 'item', $attr = '', $id = 'id', $encoding = 'utf-8')
    {
        if (is_array($attr)) {
            $_attr = array();
            foreach ($attr as $key => $value) {
                $_attr[] = "{$key}=\"{$value}\"";
            }
            $attr = implode(' ', $_attr);
        }
        $attr = trim($attr);
        $attr = empty($attr) ? '' : " {$attr}";
        $xml = "<{$root}{$attr}>";
        $xml .= self::data_to_xml($data, $item, $id);
        $xml .= "</{$root}>";
        return $xml;
    }

    /**
     * 过滤文字回复\r\n换行符
     * @param string $text
     * @return string|mixed
     */
    private function _auto_text_filter($text)
    {
        if (!$this->_text_filter) return $text;
        return str_replace("\r\n", "\n", $text);
    }

    /**
     * 设置回复消息
     * Example: $obj->text('hello')->reply();
     * @param string $text
     */
    public function text($text = '')
    {

        $FuncFlag = $this->_funcflag ? 1 : 0;
        $msg = array(
            'ToUserName' => $this->getRevFrom(),
            'FromUserName' => $this->getRevTo(),
            'MsgType' => self::MSGTYPE_TEXT,
            'Content' => $this->_auto_text_filter($text),
            'CreateTime' => time(),
            'FuncFlag' => $FuncFlag
        );

        $this->Message($msg);

        return $this;

    }

    /**
     * 设置回复消息
     * Example: $obj->image('media_id')->reply();
     * @param string $mediaid
     */
    public function image($mediaid = '')
    {
        $FuncFlag = $this->_funcflag ? 1 : 0;
        $msg = array(
            'ToUserName' => $this->getRevFrom(),
            'FromUserName' => $this->getRevTo(),
            'MsgType' => self::MSGTYPE_IMAGE,
            'Image' => array('MediaId' => $mediaid),
            'CreateTime' => time(),
            'FuncFlag' => $FuncFlag
        );
        $this->Message($msg);
        return $this;
    }

    /**
     * 设置回复消息
     * Example: $obj->voice('media_id')->reply();
     * @param string $mediaid
     */
    public function voice($mediaid = '')
    {
        $FuncFlag = $this->_funcflag ? 1 : 0;
        $msg = array(
            'ToUserName' => $this->getRevFrom(),
            'FromUserName' => $this->getRevTo(),
            'MsgType' => self::MSGTYPE_VOICE,
            'Voice' => array('MediaId' => $mediaid),
            'CreateTime' => time(),
            'FuncFlag' => $FuncFlag
        );
        $this->Message($msg);
        return $this;
    }

    /**
     * 设置回复消息
     * Example: $obj->video('media_id','title','description')->reply();
     * @param string $mediaid
     */
    public function video($mediaid = '', $title = '', $description = '')
    {
        $FuncFlag = $this->_funcflag ? 1 : 0;
        $msg = array(
            'ToUserName' => $this->getRevFrom(),
            'FromUserName' => $this->getRevTo(),
            'MsgType' => self::MSGTYPE_VIDEO,
            'Video' => array(
                'MediaId' => $mediaid,
                'Title' => $title,
                'Description' => $description
            ),
            'CreateTime' => time(),
            'FuncFlag' => $FuncFlag
        );
        $this->Message($msg);
        return $this;
    }

    /**
     * 设置回复音乐
     * @param string $title
     * @param string $desc
     * @param string $musicurl
     * @param string $hgmusicurl
     * @param string $thumbmediaid 音乐图片缩略图的媒体id，非必须
     */
    public function music($title, $desc, $musicurl, $hgmusicurl = '', $thumbmediaid = '')
    {
        $FuncFlag = $this->_funcflag ? 1 : 0;
        $msg = array(
            'ToUserName' => $this->getRevFrom(),
            'FromUserName' => $this->getRevTo(),
            'CreateTime' => time(),
            'MsgType' => self::MSGTYPE_MUSIC,
            'Music' => array(
                'Title' => $title,
                'Description' => $desc,
                'MusicUrl' => $musicurl,
                'HQMusicUrl' => $hgmusicurl
            ),
            'FuncFlag' => $FuncFlag
        );
        if ($thumbmediaid) {
            $msg['Music']['ThumbMediaId'] = $thumbmediaid;
        }
        $this->Message($msg);
        return $this;
    }

    /**
     * 设置回复图文
     * @param array $newsData
     * 数组结构:
     *  array(
     *    "0"=>array(
     *        'Title'=>'msg title',
     *        'Description'=>'summary text',
     *        'PicUrl'=>'http://www.domain.com/1.jpg',
     *        'Url'=>'http://www.domain.com/1.html'
     *    ),
     *    "1"=>....
     *  )
     */
    public function news($newsData = array())
    {
        $FuncFlag = $this->_funcflag ? 1 : 0;
        $count = count($newsData);
        $msg = array(
            'ToUserName' => $this->getRevFrom(),
            'FromUserName' => $this->getRevTo(),
            'MsgType' => self::MSGTYPE_NEWS,
            'CreateTime' => time(),
            'ArticleCount' => $count,
            'Articles' => $newsData,
            'FuncFlag' => $FuncFlag
        );
        $this->Message($msg);
        return $this;
    }

    /**
     *
     * 回复微信服务器, 此函数支持链式操作
     * Example: $this->text('msg tips')->reply();
     * @param string $msg 要发送的信息, 默认取$this->_msg
     * @param bool $return 是否返回信息而不抛出到浏览器 默认:否
     */
    public function reply($msg = array(), $return = false)
    {

        if (empty($msg)) {
            if (empty($this->_msg))   //防止不先设置回复内容，直接调用reply方法导致异常
                return false;
            $msg = $this->_msg;
        }
        $xmldata = $this->xml_encode($msg);

        $this->log($xmldata);
        if ($this->encrypt_type == 'aes') { //如果来源消息为加密方式
            $pc = new Prpcrypt($this->component_encodingAesKey);
            $array = $pc->encrypt($xmldata, $this->component_appid);
            $ret = $array[0];
            if ($ret != 0) {
                $this->log('encrypt err!');
                return false;
            }
            $timestamp = time();
            $nonce = rand(77, 999) * rand(605, 888) * rand(11, 99);
            $encrypt = $array[1];
            $tmpArr = array($this->component_token, $timestamp, $nonce, $encrypt);//比普通公众平台多了一个加密的密文
            sort($tmpArr, SORT_STRING);
            $signature = implode($tmpArr);
            $signature = sha1($signature);
            $xmldata = $this->generate($encrypt, $signature, $timestamp, $nonce);
            $this->log($xmldata);
        }

        if ($return) {

            return $xmldata;
        } else {


            echo $xmldata;
        }
    }

    /**
     * 模板消息 获取模版消息列表
     * @param int $id1 公众号模板消息所属行业编号，参看官方开发文档 行业代码
     * @param int $id2 同$id1。但如果只有一个行业，此参数可省略
     * @return boolean|array
     */
    public function getTMPList()
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $result = $this->http_get(self::API_URL_PREFIX . self::TEMPLATE_GET_ALL_PRIVATE_TEMPLATE . 'access_token=' . $this->get_authorizer_access_token());
        if ($result) {
            $json = json_decode($result, true);
            return $json;
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }

    /**
     * 模板消息 获取所属行业
     * @param int $id1 公众号模板消息所属行业编号，参看官方开发文档 行业代码
     * @param int $id2 同$id1。但如果只有一个行业，此参数可省略
     * @return boolean|array
     */
    public function getTMIndustry()
    {

        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $result = $this->http_get(self::API_URL_PREFIX . self::TEMPLATE_GET_INDUSTRY . 'access_token=' . $this->get_authorizer_access_token());
        if ($result) {
            $json = json_decode($result, true);
            return $json;
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }


    /**
     * 模板消息 设置所属行业
     * @param int $id1 公众号模板消息所属行业编号，参看官方开发文档 行业代码
     * @param int $id2 同$id1。但如果只有一个行业，此参数可省略
     * @return boolean|array
     */
    public function setTMIndustry($id1, $id2 = '')
    {
        if ($id1) $data['industry_id1'] = $id1;
        if ($id2) $data['industry_id2'] = $id2;
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $result = $this->http_post(self::API_URL_PREFIX . self::TEMPLATE_SET_INDUSTRY_URL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data));
        if ($result) {
            $json = json_decode($result, true);
            return $json;
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }

    /**
     * 模板消息 添加消息模板
     * 成功返回消息模板的调用id
     * @param string $tpl_id 模板库中模板的编号，有“TM**”和“OPENTMTM**”等形式
     * @return boolean|string
     */
    public function addTemplateMessage($tpl_id)
    {
        $data = array('template_id_short' => $tpl_id);
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $result = $this->http_post(self::API_URL_PREFIX . self::TEMPLATE_ADD_TPL_URL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data));
        if ($result) {

            $json = json_decode($result, true);
            return $json;
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json['template_id'];
        }
        return false;
    }

    /**
     * 发送模板消息
     * @param array $data 消息结构
     * ｛
     * "touser":"OPENID",
     * "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
     * "url":"http://weixin.qq.com/download",
     * "topcolor":"#FF0000",
     * "data":{
     * "参数名1": {
     * "value":"参数",
     * "color":"#173177"     //参数颜色
     * },
     * "Date":{
     * "value":"06月07日 19时24分",
     * "color":"#173177"
     * },
     * "CardNumber":{
     * "value":"0426",
     * "color":"#173177"
     * },
     * "Type":{
     * "value":"消费",
     * "color":"#173177"
     * }
     * }
     * }
     * @return boolean|array
     */
    public function sendTemplateMessage($data)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;

        $result = $this->http_post(self::API_URL_PREFIX . self::TEMPLATE_SEND_URL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data));

        if ($result) {
            $json = json_decode($result, true);
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];

                return $json;
            }
            return $json;
        }
        return false;
    }

    //js_sdk
    public function resetJsTicket($appid = '')
    {
        if (!$appid) $appid = $this->authorizer_appid;
        $this->jsapi_ticket = '';
        $authname = 'wechat_jsapi_ticket' . $appid;
        S($authname, '');
        return true;
    }


    /*
     * 打开指定卡券列表
     * 需要传入Card_id和code
     */
    public function wxOpenCard($data)
    {

        return json_encode($data);
    }

    /*
     * 配置要投放的卡券
     * 需要时间戳,随机字符串,Card_id,CardTicket,卡券签名
     *
     */
    public function wxAddCard($openid = '', $card_id, $noncestr, $outer_str = '')
    {
        $cardticket = $this->getCardJsTicket();
//        $cardticket = 'IpK_1T69hDhZkLQTlwsAX0kf3M5iOKQbWgHLHVPpOzUsHdhW-vPRmTmYlr4mc6fucPVOz33l3b-PKV79jjlWvA';
        //     $noncestr = $this->generateNonceStr();
        $timestamp = time();
        //       $cardid = $card_id;
        $data = array($cardticket, $timestamp, $noncestr, $card_id);
        if ($openid != '') {
            $data = array($openid, $cardticket, $timestamp, $noncestr, $card_id);
        }
        $signature = $this->getCardSignature($data);

        $cardExt = array('nonce_str' => $noncestr, 'timestamp' => $timestamp, 'signature' => $signature);
        if ($outer_str !== '') {
            $cardExt['outer_str'] = $outer_str;
        }
        if ($openid !== '') {
            $cardExt['openid'] = $openid;
        }
        //       $AddCard = array('cardId' => $cardid,'cardExt' =>json_encode($cardExt));
        return json_encode($cardExt);
    }

    /*
     * 配置要投放的卡券
     * 需要时间戳,随机字符串,Card_id,CardTicket,卡券签名
     *
     */
    public function wxAddCardOpenid($openid = '', $card_id, $noncestr)
    {
        $cardticket = $this->getCardJsTicket();
        //     $noncestr = $this->generateNonceStr();
        $timestamp = time();
        //       $cardid = $card_id;
        $data = array($cardticket, $timestamp, $openid, $noncestr, $card_id);
        $signature = $this->getCardSignature($data);
        $cardExt = array('nonce_str' => $noncestr, 'openid' => $openid, 'timestamp' => $timestamp, 'signature' => $signature,);
        //       $AddCard = array('cardId' => $cardid,'cardExt' =>json_encode($cardExt));
        return json_encode($cardExt);
    }

    /*
        * 配置要投放的卡券
        * 需要时间戳,随机字符串,Card_id,CardTicket,卡券签名
        *
        */
    public function wxAddCardShare($card_id, $outer_str, $noncestr)
    {
        $cardticket = $this->getCardJsTicket();
        //     $noncestr = $this->generateNonceStr();
        $timestamp = time();
        //       $cardid = $card_id;
        $data = array($cardticket, $timestamp, $noncestr, $card_id);
        $signature = $this->getCardSignature($data);
        $cardExt = array('nonce_str' => $noncestr, "outer_str" => $outer_str, 'timestamp' => $timestamp, 'signature' => $signature,);
        //       $AddCard = array('cardId' => $cardid,'cardExt' =>json_encode($cardExt));
        return json_encode($cardExt);
    }

    /*
     * 卡券签名
     * 需要时间戳,随机字符串,Card_id,CardTicket
     *
     */
    public function getCardSignature($arrdata, $method = "sha1")
    {
        if (!function_exists($method)) {
            return false;
        }
        $newArray = array();
        foreach ($arrdata as $value) {
            array_push($newArray, (string)$value);
        }
        sort($newArray, SORT_STRING);
        return $method(implode($newArray));
    }

    /**
     * 获取JSAPI卡券授权TICKET
     * @param string $appid 用于多个appid时使用,可空
     * @param string $jsapi_card_ticket 手动指定jsapi_card_ticket，非必要情况不建议用
     */
    public function getCardJsTicket($appid = '', $jsapi_card_ticket = '')
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        if (!$appid) $appid = $this->authorizer_appid;
        if ($jsapi_card_ticket) { //手动指定token，优先使用
            $this->jsapi_card_ticket = $jsapi_card_ticket;
            return $this->jsapi_card_ticket;
        }
        $authname = 'wechat_jsapi_card_ticket' . $appid;
        if ($rs = Cookie::get($authname)) {
            $this->jsapi_card_ticket = $rs;
            return $rs;
        }
        $result = $this->http_get(self::API_URL_PREFIX . self::GET_TICKET_URL . 'access_token=' . $this->get_authorizer_access_token() . '&type=wx_card');
//        return $result;
        if ($result) {
            $json = json_decode($result, true);
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            $this->jsapi_card_ticket = $json['ticket'];
            $expire = $json['expires_in'] ? intval($json['expires_in']) - 100 : 3600;
            Cookie::set($authname, $json['ticket'], $expire);
            return $this->jsapi_card_ticket;
        }
        return false;
    }


    public function get_card_JsSign2($url, $timestamp = 0, $noncestr = '', $appid = '')
    {
        if (!$this->jsapi_card_ticket && !$this->getCardJsTicket($appid) || !$url) return false;
        if (!$timestamp)
            $timestamp = time();
        if (!$noncestr)
            $noncestr = $this->generateNonceStr();
        $ret = strpos($url, '#');
        if ($ret)
            $url = substr($url, 0, $ret);
        $url = trim($url);
        if (empty($url))
            return false;
//        $ticket = 'IpK_1T69hDhZkLQTlwsAX0kf3M5iOKQbWgHLHVPpOzUGDwpSPoHJyqZ2RFsG87iT6yaBbSg7aYVKaWrGqTVvlg';
        $arrdata = array("timestamp" => $timestamp, "noncestr" => $noncestr, "url" => $url, "jsapi_ticket" => $this->jsapi_card_ticket);
        $sign = $this->getSignature($arrdata);
        if (!$sign)
            return false;
        $signPackage = array(
            "appId" => $this->authorizer_appid,
            "nonceStr" => $noncestr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $sign,
            "ticket" => $ticket,
        );
        return $signPackage;
    }

    public function get_card_JsSign($url, $timestamp = 0, $noncestr = '', $appid = '')
    {
        if (!$this->jsapi_ticket && !$this->getJsTicket($appid) || !$url) return false;
        if (!$timestamp)
            $timestamp = time();
        if (!$noncestr)
            $noncestr = $this->generateNonceStr();
        $ret = strpos($url, '#');
        if ($ret)
            $url = substr($url, 0, $ret);
        $url = trim($url);
        if (empty($url))
            return false;
        $arrdata = array("timestamp" => $timestamp, "noncestr" => $noncestr, "url" => $url, "jsapi_ticket" => $this->jsapi_card_ticket);
        $sign = $this->getSignature($arrdata);
        if (!$sign)
            return false;
        $signPackage = array(
            "appId" => $this->authorizer_appid,
            "nonceStr" => $noncestr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $sign,
            "ticket" => $this->jsapi_ticket,
        );
        return $signPackage;
    }

    public function get_card_JsSign_Openid($url, $openid, $timestamp = 0, $noncestr = '', $appid = '')
    {
        if (!$this->jsapi_ticket && !$this->getJsTicket($appid) || !$url) return false;
        if (!$timestamp)
            $timestamp = time();
        if (!$noncestr)
            $noncestr = $this->generateNonceStr();
        $ret = strpos($url, '#');
        if ($ret)
            $url = substr($url, 0, $ret);
        $url = trim($url);
        if (empty($url))
            return false;
        $arrdata = array("timestamp" => $timestamp, "noncestr" => $noncestr, "openid" => $openid, "url" => $url, "jsapi_ticket" => $this->jsapi_card_ticket);
        $sign = $this->getSignature($arrdata);
        if (!$sign)
            return false;
        $signPackage = array(
            "appId" => $this->authorizer_appid,
            "nonceStr" => $noncestr,
            "timestamp" => $timestamp,
            "url" => $url,
            "openid" => $openid,
            "signature" => $sign,
            "ticket" => $this->jsapi_ticket,
        );
        return $signPackage;
    }

    /**
     * 获取JSAPI授权TICKET
     * @param string $appid 用于多个appid时使用,可空
     * @param string $jsapi_ticket 手动指定jsapi_ticket，非必要情况不建议用
     */
    public function getJsTicket($appid = '', $jsapi_ticket = '')
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        if (!$appid) $appid = $this->authorizer_appid;
        if ($jsapi_ticket) { //手动指定token，优先使用
            $this->jsapi_ticket = $jsapi_ticket;
            return $this->jsapi_ticket;
        }
        $authname = 'wechat_jsapi_ticket' . $appid;
        if ($rs = Cookie::get($authname)) {
            $this->jsapi_ticket = $rs;
            return $rs;
        }
        $result = $this->http_get(self::API_URL_PREFIX . self::GET_TICKET_URL . 'access_token=' . $this->get_authorizer_access_token() . '&type=jsapi');
        if ($result) {
            $json = json_decode($result, true);
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            $this->jsapi_ticket = $json['ticket'];
            $expire = $json['expires_in'] ? intval($json['expires_in']) - 100 : 3600;
            Cookie::set($authname, $this->jsapi_ticket, $expire);
            return $this->jsapi_ticket;
        }
        return false;
    }

    /**
     * 获取JsApi使用签名
     * @param string $url 网页的URL，自动处理#及其后面部分
     * @param string $timestamp 当前时间戳 (为空则自动生成)
     * @param string $noncestr 随机串 (为空则自动生成)
     * @param string $appid 用于多个appid时使用,可空
     * @return array|bool 返回签名字串
     */
    public function getJsSign2($url, $timestamp = 0, $noncestr = '', $appid = '')
    {
        if (!$this->jsapi_ticket && !$this->getJsTicket($appid) || !$url) return false;
        if (!$timestamp)
            $timestamp = time();
        if (!$noncestr)
            $noncestr = $this->generateNonceStr();
        $ret = strpos($url, '#');
        if ($ret)
            $url = substr($url, 0, $ret);
        $url = trim($url);
        if (empty($url))
            return false;
        $arrdata = array("timestamp" => $timestamp, "noncestr" => $noncestr, "url" => $url, "jsapi_ticket" => $this->jsapi_ticket);
        $sign = $this->getSignature2($arrdata);
//        if (!$sign)
//            return false;
//        $signPackage = array(
//            "appId" => $this->authorizer_appid,
//            "nonceStr" => $noncestr,
//            "timestamp" => $timestamp,
//            "url" => $url,
//            "signature" => $sign,
//            "ticket" => $this->jsapi_ticket,
//        );
        return $sign;
    }

    public function getJsSign($url, $timestamp = 0, $noncestr = '', $appid = '')
    {
        if (!$this->jsapi_ticket && !$this->getJsTicket($appid) || !$url) return false;
        if (!$timestamp)
            $timestamp = time();
        if (!$noncestr)
            $noncestr = $this->generateNonceStr();
        $ret = strpos($url, '#');
        if ($ret)
            $url = substr($url, 0, $ret);
        $url = trim($url);
        if (empty($url))
            return false;
        $arrdata = array("timestamp" => $timestamp, "noncestr" => $noncestr, "url" => $url, "jsapi_ticket" => $this->jsapi_ticket);
        $sign = $this->getSignature($arrdata);
        if (!$sign)
            return false;
        $signPackage = array(
            "appId" => $this->authorizer_appid,
            "nonceStr" => $noncestr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $sign,
            "ticket" => $this->jsapi_ticket,
        );
        return $signPackage;
    }

    /**
     * 生成随机字串
     * @param number $length 长度，默认为16，最长为32字节
     * @return string
     */
    public function generateNonceStr($length = 16)
    {
        // 密码字符集，可任意添加你需要的字符
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= $chars[mt_rand(0, strlen($chars) - 1)];
        }
        return $str;
    }

    //刷卡支付
    public function createmicroPackageXml($appid, $sub_appid, $mch_id, $out_trade_no, $body, $sub_mch_id, $total_fee, $spbill_create_ip, $nonce_str, $auth_code)
    {
        if (strlen($sub_mch_id) > 6) {
            $arrdata = array("appid" => $appid, 'sub_appid' => $sub_appid, "mch_id" => $mch_id, "sub_mch_id" => $sub_mch_id, "nonce_str" => $nonce_str, "body" => $body, "out_trade_no" => $out_trade_no, "total_fee" => $total_fee, "spbill_create_ip" => $spbill_create_ip, "auth_code" => $auth_code);
        } else {
            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "nonce_str" => $nonce_str, "body" => $body, "out_trade_no" => $out_trade_no, "total_fee" => $total_fee, "spbill_create_ip" => $spbill_create_ip, "auth_code" => $auth_code);


        }
        if (empty($sub_appid)) {
            unset($arrdata['sub_appid']);
        }
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $this->partnerkey;
        $signValue = strtoupper(md5($stringSignTemp));

        if (strlen($sub_mch_id) > 6) {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					    <sub_appid>" . $sub_appid . "</sub_appid>
					   <mch_id>" . $mch_id . "</mch_id>
					    <auth_code>" . $auth_code . "</auth_code>
                        <sub_mch_id>" . $sub_mch_id . "</sub_mch_id>  
					   <nonce_str>" . $nonce_str . "</nonce_str>
					   <sign>" . $signValue . "</sign>
					   <body>" . $body . "</body>
					   <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <total_fee>" . $total_fee . "</total_fee>
					   <spbill_create_ip>" . $spbill_create_ip . "</spbill_create_ip>
					 
					</xml>";
        } else {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
                        <auth_code>" . $auth_code . "</auth_code>               
					   <nonce_str>" . $nonce_str . "</nonce_str>
					   <sign>" . $signValue . "</sign>
					   <body>" . $body . "</body>
					   <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <total_fee>" . $total_fee . "</total_fee>
					   <spbill_create_ip>" . $spbill_create_ip . "</spbill_create_ip>
					
					</xml>";


        }
        return $returValue;


    }

    public function sand_boxcreatemicroPackageXml($appid, $sub_appid, $mch_id, $out_trade_no, $body, $sub_mch_id, $total_fee, $spbill_create_ip, $nonce_str, $auth_code, $sandboxkey = "")
    {
        if (strlen($sub_mch_id) > 6) {
            $arrdata = array("appid" => $appid, 'sub_appid' => $sub_appid, "mch_id" => $mch_id, "sub_mch_id" => $sub_mch_id, "nonce_str" => $nonce_str, "body" => $body, "out_trade_no" => $out_trade_no, "total_fee" => $total_fee, "spbill_create_ip" => $spbill_create_ip, "auth_code" => $auth_code);
        } else {
            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "nonce_str" => $nonce_str, "body" => $body, "out_trade_no" => $out_trade_no, "total_fee" => $total_fee, "spbill_create_ip" => $spbill_create_ip, "auth_code" => $auth_code);


        }
        if (empty($sub_appid)) {
            unset($arrdata['sub_appid']);
        }
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $sandboxkey;
        $signValue = strtoupper(md5($stringSignTemp));

        if (strlen($sub_mch_id) > 6) {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					    <sub_appid>" . $sub_appid . "</sub_appid>
					   <mch_id>" . $mch_id . "</mch_id>
					    <auth_code>" . $auth_code . "</auth_code>
                        <sub_mch_id>" . $sub_mch_id . "</sub_mch_id>  
					   <nonce_str>" . $nonce_str . "</nonce_str>
					   <sign>" . $signValue . "</sign>
					   <body>" . $body . "</body>
					   <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <total_fee>" . $total_fee . "</total_fee>
					   <spbill_create_ip>" . $spbill_create_ip . "</spbill_create_ip>
					 
					</xml>";
        } else {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
                        <auth_code>" . $auth_code . "</auth_code>               
					   <nonce_str>" . $nonce_str . "</nonce_str>
					   <sign>" . $signValue . "</sign>
					   <body>" . $body . "</body>
					   <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <total_fee>" . $total_fee . "</total_fee>
					   <spbill_create_ip>" . $spbill_create_ip . "</spbill_create_ip>
					
					</xml>";


        }
        return $returValue;


    }

    //微信支付
    public function createPackageXml($appid, $sub_appid, $mch_id, $sub_mch_id, $nonce_str, $body, $out_trade_no, $total_fee, $spbill_create_ip, $notify_url, $openid)
    {
        if (strlen($sub_mch_id) > 6) {
            $arrdata = array("appid" => $appid, 'sub_appid' => $sub_appid, "mch_id" => $mch_id, "sub_mch_id" => $sub_mch_id, "nonce_str" => $nonce_str, "body" => $body, "out_trade_no" => $out_trade_no, "total_fee" => $total_fee, "spbill_create_ip" => $spbill_create_ip, "notify_url" => $notify_url, "openid" => $openid, 'trade_type' => 'JSAPI');
        } else {
            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "nonce_str" => $nonce_str, "body" => $body, "out_trade_no" => $out_trade_no, "total_fee" => $total_fee, "spbill_create_ip" => $spbill_create_ip, "notify_url" => $notify_url, "openid" => $openid, 'trade_type' => 'JSAPI');


        }
        if (empty($sub_appid)) {
            unset($arrdata['sub_appid']);
        }

        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $this->partnerkey;

        $signValue = strtoupper(md5($stringSignTemp));


        if (strlen($sub_mch_id) > 6) {

            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					 <sub_appid>" . $sub_appid . "</sub_appid>
					   <mch_id>" . $mch_id . "</mch_id>
                       <sub_mch_id>" . $sub_mch_id . "</sub_mch_id>  
					   <nonce_str>" . $nonce_str . "</nonce_str>
					   <sign>" . $signValue . "</sign>
					   <body>" . $body . "</body>
					   <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <total_fee>" . $total_fee . "</total_fee>
					   <spbill_create_ip>" . $spbill_create_ip . "</spbill_create_ip>
					   <notify_url>" . $notify_url . "</notify_url>
					   <trade_type>JSAPI</trade_type>
					   <openid>" . $openid . "</openid>
					</xml>";
        } else {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
                                       
					   <nonce_str>" . $nonce_str . "</nonce_str>
					   <sign>" . $signValue . "</sign>
					   <body>" . $body . "</body>
					   <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <total_fee>" . $total_fee . "</total_fee>
					   <spbill_create_ip>" . $spbill_create_ip . "</spbill_create_ip>
					   <notify_url>" . $notify_url . "</notify_url>
					   <trade_type>JSAPI</trade_type>
					   <openid>" . $openid . "</openid>
					</xml>";


        }
        return $returValue;
    }

    public function createWxPackageXml($arrdata)
    {
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (!empty($value)) {
                $arrdata2[$key] = $value;
            }


        }
        foreach ($arrdata2 as $key => $value) {

            if (strlen($paramstring) == 0)

                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $this->partnerkey;
        if(isset($arrdata['sign_type'])){
            if ($arrdata['sign_type'] == "MD5") {

                $signValue = strtoupper(md5($stringSignTemp));

            } elseif ($arrdata['sign_type'] == "HMAC-SHA256") {

                $signValue = strtoupper(hash_hmac("sha256", $stringSignTemp, $this->partnerkey));

            }
        }else {

            $signValue = strtoupper(md5($stringSignTemp));
        }


        $arrdata2['sign'] = $signValue;
        $xml = $this->arrayToXml($arrdata2);

        return $xml;
    }

    private function arrayToXml($data)
    {
        if (!is_array($data) || count($data) <= 0) {
            return false;
        }
        $xml = "<xml>";
        foreach ($data as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    //微信支付
    public function createWxPackageXmls($arrdata,$partnerkey)
    {

        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (!empty($value)) {
                $arrdata2[$key] = $value;
            }
        }
        foreach ($arrdata2 as $key => $value) {

            if (strlen($paramstring) == 0)

                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $partnerkey;
        $signValue = strtoupper(md5($stringSignTemp));
        $arrdata2['sign'] = $signValue;
        $xml = $this->arrayToXml($arrdata2);
        return $xml;
    }

    //微信支付 子商户模式
    public function createPackageXml2($appid, $sub_appid, $mch_id, $sub_mch_id, $nonce_str, $body, $out_trade_no, $total_fee, $spbill_create_ip, $notify_url, $openid, $sub_openid)
    {
        if (strlen($sub_mch_id) > 6) {
            $arrdata = array("appid" => $appid, 'sub_appid' => $sub_appid, "mch_id" => $mch_id, "sub_mch_id" => $sub_mch_id, "nonce_str" => $nonce_str, "body" => $body, "out_trade_no" => $out_trade_no, "total_fee" => $total_fee, "spbill_create_ip" => $spbill_create_ip, "notify_url" => $notify_url, "sub_openid" => $sub_openid, 'trade_type' => 'JSAPI');
        } else {
            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "nonce_str" => $nonce_str, "body" => $body, "out_trade_no" => $out_trade_no, "total_fee" => $total_fee, "spbill_create_ip" => $spbill_create_ip, "notify_url" => $notify_url, "openid" => $openid, 'trade_type' => 'JSAPI');


        }


        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $this->partnerkey;

        $signValue = strtoupper(md5($stringSignTemp));


        if (strlen($sub_mch_id) > 6) {

            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <sub_appid>" . $sub_appid . "</sub_appid>
					   <mch_id>" . $mch_id . "</mch_id>
                       <sub_mch_id>" . $sub_mch_id . "</sub_mch_id>  
					   <nonce_str>" . $nonce_str . "</nonce_str>
					   <sign>" . $signValue . "</sign>
					   <body>" . $body . "</body>
					   <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <total_fee>" . $total_fee . "</total_fee>
					   <spbill_create_ip>" . $spbill_create_ip . "</spbill_create_ip>
					   <notify_url>" . $notify_url . "</notify_url>
					   <trade_type>JSAPI</trade_type>
					   <sub_openid>" . $sub_openid . "</sub_openid>
					</xml>";
        } else {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
                                       
					   <nonce_str>" . $nonce_str . "</nonce_str>
					   <sign>" . $signValue . "</sign>
					   <body>" . $body . "</body>
					   <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <total_fee>" . $total_fee . "</total_fee>
					   <spbill_create_ip>" . $spbill_create_ip . "</spbill_create_ip>
					   <notify_url>" . $notify_url . "</notify_url>
					   <trade_type>JSAPI</trade_type>
					   <openid>" . $openid . "</openid>
					</xml>";


        }
        return $returValue;
    }

    //微信支付统一下单ID
    public function get_pay_id($xml)
    {
        $result = $this->http_post(self::PAY_API_URL, $xml, true);
        if ($result) {
            $json = $this->xmlToArray($result);

            return $json;


        }
        return false;
    }

    public function Mircopay_post($xml)
    {
        $result = $this->http_post(self::MICROPAY_API_URL, $xml, true);
        if ($result) {
            $json = $this->xmlToArray($result);

            return $json;


        }
        return false;
    }

    public function Mircopay_sandbox_post($xml)
    {
        $result = $this->http_post(self::SANDBOX_MICROPAY_API_URL, $xml, true);
        if ($result) {
            $json = $this->xmlToArray($result);

            return $json;


        }
        return false;
    }

    public function getPaySignature($arrdata)
    {
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }

        $paramstring = $paramstring . "&key=" . $this->partnerkey;

        $paySign = md5($paramstring);

        return $paySign;
    }

    public function getcmmbpaysignature($post_data)
    {
        $key = $this->cmmb_key;
        ksort($post_data);

        $o = "";
        foreach ($post_data as $k => $v) {
            $o .= "$k=" . ($v) . "&";
        }
        $post_data = substr($o, 0, -1);
        $post_data_temp = $post_data . $key;
        $signIn = strtoupper(md5($post_data_temp));
        return $signIn;

    }

    public function getPayNum($xml)
    {

        $result = $this->http_post(self::PAY_ORDERQUERYA, $xml, true);
        if ($result) {
            $json = $this->xmlToArray($result);
            return $json;
        }
        return false;

    }

    public function sandbox_getPayNum($xml)
    {

        $result = $this->http_post(self::SANDBOX_PAY_ORDERQUERYA, $xml, true);
        if ($result) {
            $json = $this->xmlToArray($result);
            return $json;
        }
        return false;

    }

    public function getPayRefundQuery($xml)
    {

        $result = $this->http_post(self::PAY_REFUND_QUERY, $xml, true);
        if ($result) {
            $json = $this->xmlToArray($result);
            return $json;
        }
        return false;

    }

    public function getcmmbpay($data)
    {
        $result = $this->http_post(self::CMMB_PAY_URL, $data, true);
        return $result;

    }

    public function cmmbpaytk($data)
    {
        $result = $this->http_post(self::CMMB_TUIKUAN, $data, true);
        return $result;

    }

    public function cmmbpayreverse($data)
    {
        $result = $this->http_post(self::CMMB_REVERSE, $data, true);
        return $result;
    }

    public function cmmb_order_close($data)
    {
        $result = $this->http_post(self::CMMB_ORDER_CLOSE, $data, true);
        return $result;
    }

    public function getcmmbscanpay($data)
    {
        $result = $this->http_post(self::CMMB_SCANPAY_URL, $data, true);
        return $result;

    }

    public function getcmmborderquery($data)
    {
        $result = $this->http_post(self::CMMB_ORDER_QUERY, $data, true);
        return $result;
    }

    //xml转array
    public function xmlToArray($xml)
    {
        libxml_disable_entity_loader(true);
        //将XML转为array
        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array_data;
    }

//订单退款查询xml
    public function createOrderrefundXml($appid, $mch_id, $sub_appid, $sub_mch_id, $out_refund_no, $out_trade_no, $nonce_str)
    {
        if (strlen($sub_mch_id) > 6) {
            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "sub_appid" => $sub_appid, "out_refund_no" => $out_refund_no, "sub_mch_id" => $sub_mch_id, "nonce_str" => $nonce_str, "out_trade_no" => $out_trade_no);
        } else {

            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "nonce_str" => $nonce_str, "out_refund_no" => $out_refund_no, "out_trade_no" => $out_trade_no);
        }
        if (empty($sub_appid)) {
            unset($arrdata['sub_appid']);
        }
//        return $arrdata;
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $this->partnerkey;
        $signValue = strtoupper(md5($stringSignTemp));

        if (strlen($sub_mch_id) > 6) {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
					   <sub_appid>" . $sub_appid . "</sub_appid>
					   <sub_mch_id>" . $sub_mch_id . "</sub_mch_id>
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <out_trade_no>" . $out_trade_no . "</out_trade_no>
					    <out_refund_no>" . $out_refund_no . "</out_refund_no>
					   <sign>" . $signValue . "</sign>
					   
					</xml>";
        } else {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
                                         
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <out_trade_no>" . $out_trade_no . "</out_trade_no>
					    <out_refund_no>" . $out_refund_no . "</out_refund_no>

					   <sign>" . $signValue . "</sign>
					   
					</xml>";


        }
        return $returValue;
    }

    public function sandboxcreateOrderrefundXml($appid, $mch_id, $sub_appid, $sub_mch_id, $out_refund_no, $out_trade_no, $nonce_str, $sandboxkey = "")
    {
        if (strlen($sub_mch_id) > 6) {
            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "sub_appid" => $sub_appid, "out_refund_no" => $out_refund_no, "sub_mch_id" => $sub_mch_id, "nonce_str" => $nonce_str, "out_trade_no" => $out_trade_no);
        } else {

            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "nonce_str" => $nonce_str, "out_refund_no" => $out_refund_no, "out_trade_no" => $out_trade_no);
        }
        if (empty($sub_appid)) {
            unset($arrdata['sub_appid']);
        }
//        return $arrdata;
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $sandboxkey;
        $signValue = strtoupper(md5($stringSignTemp));

        if (strlen($sub_mch_id) > 6) {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
					   <sub_appid>" . $sub_appid . "</sub_appid>
					   <sub_mch_id>" . $sub_mch_id . "</sub_mch_id>
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <out_trade_no>" . $out_trade_no . "</out_trade_no>
					    <out_refund_no>" . $out_refund_no . "</out_refund_no>
					   <sign>" . $signValue . "</sign>
					   
					</xml>";
        } else {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
                                         
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <out_trade_no>" . $out_trade_no . "</out_trade_no>
					    <out_refund_no>" . $out_refund_no . "</out_refund_no>

					   <sign>" . $signValue . "</sign>
					   
					</xml>";


        }
        return $returValue;
    }

    public function sandboxdownloadbillXml($appid, $mch_id, $sub_appid, $sub_mch_id, $bill_date, $bill_type, $nonce_str, $sandboxkey = "")
    {
        if (strlen($sub_mch_id) > 6) {
            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "sub_appid" => $sub_appid, "bill_date" => $bill_date, "bill_type" => $bill_type, "sub_mch_id" => $sub_mch_id, "nonce_str" => $nonce_str);
        } else {

            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "nonce_str" => $nonce_str, "bill_date" => $bill_date, "bill_type" => $bill_type);
        }
        if (empty($sub_appid)) {
            unset($arrdata['sub_appid']);
        }
//        return $arrdata;
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $sandboxkey;
        $signValue = strtoupper(md5($stringSignTemp));

        if (strlen($sub_mch_id) > 6) {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
					   <sub_appid>" . $sub_appid . "</sub_appid>
					   <sub_mch_id>" . $sub_mch_id . "</sub_mch_id>
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <bill_date>" . $bill_date . "</bill_date>
					    <bill_type>" . $bill_type . "</bill_type>
					   <sign>" . $signValue . "</sign>
					   
					</xml>";
        } else {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
                                         
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <bill_date>" . $bill_date . "</bill_date>
                        <bill_type>" . $bill_type . "</bill_type>
					   <sign>" . $signValue . "</sign>
					   
					</xml>";


        }
        return $returValue;
    }

//获取订单信息
    public function createOrderXml($appid, $mch_id, $sub_appid, $sub_mch_id, $out_trade_no, $nonce_str)
    {
        if (strlen($sub_mch_id) > 6) {
            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "sub_appid" => $sub_appid, "sub_mch_id" => $sub_mch_id, "nonce_str" => $nonce_str, "out_trade_no" => $out_trade_no);
        } else {

            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "nonce_str" => $nonce_str, "out_trade_no" => $out_trade_no);
        }
        if (empty($sub_appid)) {
            unset($arrdata['sub_appid']);
        }
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $this->partnerkey;
        $signValue = strtoupper(md5($stringSignTemp));

        if (strlen($sub_mch_id) > 6) {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
					   <sub_appid>" . $sub_appid . "</sub_appid>
					   <sub_mch_id>" . $sub_mch_id . "</sub_mch_id>
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <sign>" . $signValue . "</sign>
					   
					</xml>";
        } else {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
                                         
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <sign>" . $signValue . "</sign>
					   
					</xml>";


        }
        return $returValue;
    }

    public function sandboxcreateOrderXml($appid, $mch_id, $sub_appid, $sub_mch_id, $out_trade_no, $nonce_str, $sandboxkey = "")
    {
        if (strlen($sub_mch_id) > 6) {
            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "sub_appid" => $sub_appid, "sub_mch_id" => $sub_mch_id, "nonce_str" => $nonce_str, "out_trade_no" => $out_trade_no);
        } else {

            $arrdata = array("appid" => $appid, "mch_id" => $mch_id, "nonce_str" => $nonce_str, "out_trade_no" => $out_trade_no);
        }
        if (empty($sub_appid)) {
            unset($arrdata['sub_appid']);
        }
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $stringSignTemp = $paramstring . "&key=" . $sandboxkey;
        $signValue = strtoupper(md5($stringSignTemp));

        if (strlen($sub_mch_id) > 6) {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
					   <sub_appid>" . $sub_appid . "</sub_appid>
					   <sub_mch_id>" . $sub_mch_id . "</sub_mch_id>
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <sign>" . $signValue . "</sign>
					   
					</xml>";
        } else {
            $returValue = "<xml>
					   <appid>" . $appid . "</appid>
					   <mch_id>" . $mch_id . "</mch_id>
                                         
					   <nonce_str>" . $nonce_str . "</nonce_str>
					    <out_trade_no>" . $out_trade_no . "</out_trade_no>
					   <sign>" . $signValue . "</sign>
					   
					</xml>";


        }
        return $returValue;
    }

    /**
     * 获取签名
     * @param array $arrdata 签名数组
     * @param string $method 签名方法
     * @return boolean|string 签名值
     */
    public function getSignature($arrdata, $method = "sha1")
    {
        if (!function_exists($method)) return false;
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $Sign = $method($paramstring);
        return $Sign;
    }

    public function getSignature2($arrdata, $method = "sha1")
    {
        if (!function_exists($method)) return false;
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        return $paramstring;
        $Sign = $method($paramstring);
        return $Sign;
    }

    /**
     * xml格式加密，仅请求为加密方式时再用
     */

    private function generate($encrypt, $signature, $timestamp, $nonce)
    {
        //格式化加密信息
        $format = "<xml>
                    <Encrypt><![CDATA[%s]]></Encrypt>
                    <MsgSignature><![CDATA[%s]]></MsgSignature>
                    <TimeStamp>%s</TimeStamp>
                    <Nonce><![CDATA[%s]]></Nonce>
                  </xml>";
        return sprintf($format, $encrypt, $signature, $timestamp, $nonce);
    }
    //场景

    /**
     * 创建二维码ticket
     * @param int|string $scene_id 自定义追踪id,临时二维码只能用数值型
     * @param int $type 0:临时二维码；1:数值型永久二维码(此时expire参数无效)；2:字符串型永久二维码(此时expire参数无效)
     * @param int $expire 临时二维码有效期，最大为604800秒
     * @return array('ticket'=>'qrcode字串','expire_seconds'=>604800,'url'=>'二维码图片解析后的地址')
     */
    public function getQRCode($scene_id, $type = 0, $expire = 604800)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        if (!isset($scene_id)) return false;
        switch ($type) {
            case '0':
                if (!is_numeric($scene_id))
                    return false;
                $action_name = 'QR_SCENE';
                $action_info = array('scene' => (array('scene_id' => $scene_id)));
                break;
            case '1':
                if (!is_numeric($scene_id))
                    return false;
                $action_name = 'QR_LIMIT_SCENE';
                $action_info = array('scene' => (array('scene_id' => $scene_id)));
                break;
            case '2':
                if (!is_string($scene_id))
                    return false;
                $action_name = 'QR_LIMIT_STR_SCENE';
                $action_info = array('scene' => (array('scene_str' => $scene_id)));
                break;
            default:
                return false;
        }
        $data = array(
            'action_name' => $action_name,
            'expire_seconds' => $expire,
            'action_info' => $action_info
        );
        if ($type) {
            unset($data['expire_seconds']);
        }

        $result = $this->http_post(self::API_URL_PREFIX . self::QRCODE_CREATE_URL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data));

        if ($result) {
            $json = json_decode($result, true);
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json;
        }
        return false;
    }

    /**
     * 获取二维码图片
     * @param string $ticket 传入由getQRCode方法生成的ticket参数
     * @return string url 返回http地址
     */
    public function getQRUrl($ticket)
    {
        return self::QRCODE_IMG_URL . urlencode($ticket);
    }

    /**
     * 长链接转短链接接口
     * @param string $long_url 传入要转换的长url
     * @return boolean|string url 成功则返回转换后的短url
     */
    public function getShortUrl($long_url)
    {
        if (!$this->component_access_token && !$this->checkopenAuth()) return false;
        $data = array(
            'action' => 'long2short',
            'long_url' => $long_url
        );
        $result = $this->http_post(self::API_URL_PREFIX . self::SHORT_URL . 'access_token=' . $this->get_authorizer_access_token(), self::json_encode($data));
        if ($result) {
            $json = json_decode($result, true);
            if (!$json || !empty($json['errcode'])) {
                $this->errCode = $json['errcode'];
                $this->errMsg = $json['errmsg'];
                return false;
            }
            return $json['short_url'];
        }
        return false;
    }


    private function http_post($url, $param, $post_file = false)
    {
        $oCurl = curl_init();
        if (stripos($url, "https://") !== FALSE) {
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
        }
        if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) {
            $is_curlFile = true;
        } else {
            $is_curlFile = false;
            if (defined('CURLOPT_SAFE_UPLOAD')) {
                curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false);
            }
        }
        if (is_string($param)) {
            $strPOST = $param;
        } elseif ($post_file) {

            if ($is_curlFile) {
                foreach ($param as $key => $val) {

                    if (substr($val, 0, 1) == '@') {

                        $param[$key] = new \CURLFile(realpath(substr($val, 1)));

                    }
                }

            }
            $strPOST = $param;

        } else {
            $aPOST = array();
            foreach ($param as $key => $val) {
                $aPOST[] = $key . "=" . urlencode($val);
            }
            $strPOST = join("&", $aPOST);

        }

        curl_setopt($oCurl, CURLOPT_URL, $url);
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($oCurl, CURLOPT_POST, true);
        curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
        $sContent = curl_exec($oCurl);
        $aStatus = curl_getinfo($oCurl);
        curl_close($oCurl);

        if (intval($aStatus["http_code"]) == 200) {
            return $sContent;
        } else {
            return false;
        }
    }

    private function http_get($url)
    {
        $oCurl = curl_init();
        if (stripos($url, "https://") !== FALSE) {
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
        }
        curl_setopt($oCurl, CURLOPT_URL, $url);
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
        $sContent = curl_exec($oCurl);
        $aStatus = curl_getinfo($oCurl);
        curl_close($oCurl);
        if (intval($aStatus["http_code"]) == 200) {
            return $sContent;
        } else {
            return false;
        }
    }

    static function json_encode($arr)
    {
        return json_encode($arr, JSON_UNESCAPED_UNICODE);
//        if (count($arr) == 0) return "[]";
//        $parts = array();
//        $is_list = false;
//        //Find out if the given array is a numerical array
//        $keys = array_keys($arr);
//        $max_length = count($arr) - 1;
//        if (($keys [0] === 0) && ($keys [$max_length] === $max_length)) { //See if the first key is 0 and last key is length - 1
//            $is_list = true;
//            for ($i = 0; $i < count($keys); $i++) { //See if each key correspondes to its position
//                if ($i != $keys [$i]) { //A key fails at position check.
//                    $is_list = false; //It is an associative array.
//                    break;
//                }
//            }
//        }
//        foreach ($arr as $key => $value) {
//            if (is_array($value)) { //Custom handling for arrays
//                if ($is_list)
//                    $parts [] = self::json_encode($value); /* :RECURSION: */
//                else
//                    $parts [] = '"' . $key . '":' . self::json_encode($value); /* :RECURSION: */
//            } else {
//                $str = '';
//                if (!$is_list)
//                    $str = '"' . $key . '":';
//                //Custom handling for multiple data types
//                if (!is_string($value) && is_numeric($value) && $value < 2000000000)
//                    $str .= $value; //Numbers
//                elseif ($value === false)
//                    $str .= 'false'; //The booleans
//                elseif ($value === true)
//                    $str .= 'true';
//                else
//                    $str .= '"' . addslashes($value) . '"'; //All other things
//                // :TODO: Is there any more datatype we should be in the lookout for? (Object?)
//                $parts [] = $str;
//            }
//        }
//        $json = implode(',', $parts);
//        if ($is_list)
//            return '[' . $json . ']'; //Return numerical JSON
//        return '{' . $json . '}'; //Return associative JSON
    }


}

/**
 * PKCS7Encoder class
 *
 * 提供基于PKCS7算法的加解密接口.
 */
class PKCS7Encoder
{
    public static $block_size = 32;

    /**
     * 对需要加密的明文进行填充补位
     * @param $text 需要进行填充补位操作的明文
     * @return 补齐明文字符串
     */
    function encode($text)
    {
        $block_size = PKCS7Encoder::$block_size;
        $text_length = strlen($text);
        //计算需要填充的位数
        $amount_to_pad = PKCS7Encoder::$block_size - ($text_length % PKCS7Encoder::$block_size);
        if ($amount_to_pad == 0) {
            $amount_to_pad = PKCS7Encoder::block_size;
        }
        //获得补位所用的字符
        $pad_chr = chr($amount_to_pad);
        $tmp = "";
        for ($index = 0; $index < $amount_to_pad; $index++) {
            $tmp .= $pad_chr;
        }
        return $text . $tmp;
    }

    /**
     * 对解密后的明文进行补位删除
     * @param decrypted 解密后的明文
     * @return 删除填充补位后的明文
     */
    function decode($text)
    {

        $pad = ord(substr($text, -1));
        if ($pad < 1 || $pad > PKCS7Encoder::$block_size) {
            $pad = 0;
        }
        return substr($text, 0, (strlen($text) - $pad));
    }

}

/**
 * Prpcrypt class
 *
 * 提供接收和推送给公众平台消息的加解密接口.
 */
class Prpcrypt
{
    public $key;

    function __construct($k)
    {
        $this->key = base64_decode($k . "=");
    }

    /**
     * 兼容老版本php构造函数，不能在 __construct() 方法前边，否则报错
     */
    function Prpcrypt($k)
    {
        $this->key = base64_decode($k . "=");
    }

    /**
     * 对明文进行加密
     * @param string $text 需要加密的明文
     * @return string 加密后的密文
     */
    public function encrypt($text, $appid)
    {

        try {
            //获得16位随机字符串，填充到明文之前
            $random = $this->getRandomStr();//"aaaabbbbccccdddd";
            $text = $random . pack("N", strlen($text)) . $text . $appid;
            // 网络字节序
            $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
            $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
            $iv = substr($this->key, 0, 16);
            //使用自定义的填充方式对明文进行补位填充
            $pkc_encoder = new PKCS7Encoder;
            $text = $pkc_encoder->encode($text);
            mcrypt_generic_init($module, $this->key, $iv);
            //加密
            $encrypted = mcrypt_generic($module, $text);
            mcrypt_generic_deinit($module);
            mcrypt_module_close($module);

            //			print(base64_encode($encrypted));
            //使用BASE64对加密后的字符串进行编码
            return array(ErrorCode::$OK, base64_encode($encrypted));
        } catch (Exception $e) {
            //print $e;
            return array(ErrorCode::$EncryptAESError, null);
        }
    }

    /**
     * 对密文进行解密
     * @param string $encrypted 需要解密的密文
     * @return string 解密得到的明文
     */
    public function decrypt($encrypted, $appid)
    {

        try {
            //使用BASE64对需要解密的字符串进行解码
            $ciphertext_dec = base64_decode($encrypted);
            $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
            $iv = substr($this->key, 0, 16);
            mcrypt_generic_init($module, $this->key, $iv);
            //解密
            $decrypted = mdecrypt_generic($module, $ciphertext_dec);
            mcrypt_generic_deinit($module);
            mcrypt_module_close($module);
        } catch (Exception $e) {
            return array(ErrorCode::$DecryptAESError, null);
        }


        try {
            //去除补位字符
            $pkc_encoder = new PKCS7Encoder;
            $result = $pkc_encoder->decode($decrypted);
            //去除16位随机字符串,网络字节序和AppId
            if (strlen($result) < 16)
                return "";
            $content = substr($result, 16, strlen($result));
            $len_list = unpack("N", substr($content, 0, 4));
            $xml_len = $len_list[1];
            $xml_content = substr($content, 4, $xml_len);
            $from_appid = substr($content, $xml_len + 4);
            if (!$appid)
                $appid = $from_appid;
            //如果传入的appid是空的，则认为是订阅号，使用数据中提取出来的appid
        } catch (Exception $e) {
            //print $e;
            return array(ErrorCode::$IllegalBuffer, null);
        }
        if ($from_appid != $appid)
            return array(ErrorCode::$ValidateAppidError, null);
        //不注释上边两行，避免传入appid是错误的情况
        return array(0, $xml_content, $from_appid); //增加appid，为了解决后面加密回复消息的时候没有appid的订阅号会无法回复

    }


    /**
     * 随机生成16位字符串
     * @return string 生成的字符串
     */
    function getRandomStr()
    {

        $str = "";
        $str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($str_pol) - 1;
        for ($i = 0; $i < 16; $i++) {
            $str .= $str_pol[mt_rand(0, $max)];
        }
        return $str;
    }

}

/**
 * error code
 * 仅用作类内部使用，不用于官方API接口的errCode码
 */
class ErrorCode
{
    public static $OK = 0;
    public static $ValidateSignatureError = 40001;
    public static $ParseXmlError = 40002;
    public static $ComputeSignatureError = 40003;
    public static $IllegalAesKey = 40004;
    public static $ValidateAppidError = 40005;
    public static $EncryptAESError = 40006;
    public static $DecryptAESError = 40007;
    public static $IllegalBuffer = 40008;
    public static $EncodeBase64Error = 40009;
    public static $DecodeBase64Error = 40010;
    public static $GenReturnXmlError = 40011;
    public static $errCode = array(
        '0' => '处理成功',
        '40001' => '校验签名失败',
        '40002' => '解析xml失败',
        '40003' => '计算签名失败',
        '40004' => '不合法的AESKey',
        '40005' => '校验AppID失败',
        '40006' => 'AES加密失败',
        '40007' => 'AES解密失败',
        '40008' => '公众平台发送的xml不合法',
        '40009' => 'Base64编码失败',
        '40010' => 'Base64解码失败',
        '40011' => '公众帐号生成回包xml失败'
    );

    public static function getErrText($err)
    {
        if (isset(self::$errCode[$err])) {
            return self::$errCode[$err];
        } else {
            return false;
        };
    }
}